因此,假设我有一个脚本,用于find
打印带有空终止文件名的路径。
我还想打印输出的另一个版本,其中每个路径按其基本名称排序。我想在不find
再次运行的情况下实现此目的,并将两个输出管道传输到同一命令,就好像它们是单个输出一样。
我认为这可以使用 Perl 来完成,但我对它不是很熟悉。
以下是需要考虑的一些重要要点:
初始输出应保持不变且实时传递。换句话说,在第一次运行期间,该命令应该简单地将行按原样输出到第二个命令,同时捕获它们以便在输入(例如,
find
)完成后进行排序。在
find
(或任何其他输出以零结尾的路径的程序)完成之后,脚本应按其基本名称对每个接收到的路径进行排序。排序应忽略最后一个/
字符之前的所有内容,除非路径以尾部斜杠结尾。在尾部斜杠的情况下,排序应基于其前面的字段,以确保具有尾部斜杠的目录不会组合在一起。排序完成后,排序后的输出应打印在原始输出之后。
如何才能轻松实现这一目标?
答案1
对于 Perl,这可能看起来像:
find . ... -print0 |
perl -MFile::Basename -0 -lne '
print; push @files, $_;
END {
print $_->[0] for sort {$a->[1] cmp $b->[1]} map {[$_, basename$_]} @files
}' | ...
和:
-MFile::Basename
use
s其功能File::Basename
M
的模块basename()
-0
:将输入记录分隔符设置为NUL字节-n
:针对每个输入记录运行 xpressionsed -n
的模式。-e
-l
:将输出记录分隔符设置为与输入记录分隔符(此处为 NUL)相同,并从记录末尾剥离输入记录分隔符,以便$_
在表达式中包含记录的内容-e
。- 对于每条记录,我们将
print
其(后跟输出记录分隔符),然后将push
其放入@files
列表中。 - 在 中
END
,我们循环遍历sort
a 的 ed 列表施瓦茨变换列表中的。