将空终止的文件路径两次管道传输到相同的输出,但第二次按基本名称排序

将空终止的文件路径两次管道传输到相同的输出,但第二次按基本名称排序

因此,假设我有一个脚本,用于find打印带有空终止文件名的路径。

我还想打印输出的另一个版本,其中每个路径按其基本名称排序。我想在不find再次运行的情况下实现此目的,并将两个输出管道传输到同一命令,就好像它们是单个输出一样。

我认为这可以使用 Perl 来完成,但我对它不是很熟悉。

以下是需要考虑的一些重要要点:

  1. 初始输出应保持不变且实时传递。换句话说,在第一次运行期间,该命令应该简单地将行按原样输出到第二个命令,同时捕获它们以便在输入(例如,find)完成后进行排序。

  2. 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 uses其功能File::Basename M的模块basename()
  • -0:将输入记录分隔符设置为NUL字节
  • -n:针对每个输入记录运行 xpressionsed -n的模式。-e
  • -l:将输出记录分隔符设置为与输入记录分隔符(此处为 NUL)相同,并从记录末尾剥离输入记录分隔符,以便$_在表达式中包含记录的内容-e
  • 对于每条记录,我们将print其(后跟输出记录分隔符),然后将push其放入@files列表中。
  • 在 中END,我们循环遍历sorta 的 ed 列表施瓦茨变换列表中的。

相关内容