通过管道将文件列表传递给 perl 脚本

Pass a list of files to perl script via pipe

我遇到一个问题,我的 perl 脚本在输入管道时会失败,但当我单独列出所有文件名时工作正常。

作为参考,perl 脚本的输入是用 while(<>) 读取的。

示例:

script.pl file1.tag file2.tag file3.tag

运行良好。

但是下面都失败了

find ./*.tag | chomp | script.pl
ls -l *.tag | perl -pe 's/\n/ /g' | script.pl
find ./*.tag | perl -pe 's/\n/ /g' | script.pl

我还测试了将它转储到一个文本文件中并将其放入 perl 中:

cat files.text | script.pl

他们都以同样的方式失败。这就像脚本没有传递任何输入参数,程序刚刚结束。

你需要 xargs,例如

 find ./ -type f -name "*.tag" | xargs -i script.pl {}

什么是 chomp?

来自 perldoc perlop:

The null filehandle <> is special [...] Input from <> comes either from standard input, or from each file listed on the command line. Here's how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to -, which when opened gives you standard input. The @ARGV array is then processed as a list of filenames.

您没有将任何命令行参数传递给您的 Perl 脚本,因此您输入它们的所有内容都会被读入 STDIN 而不是被视为文件名:

$ echo foo > foo.txt
$ echo bar > bar.txt
$ ls | perl -e 'print "<$_>\n" while <>'
<bar.txt
>
<foo.txt
>

注意文件 foo.txtbar.txt 实际上并没有被读取;我们得到的只是文件名。如果要打开和读取文件,则必须将它们作为命令行参数传递或显式设置 @ARGV:

$ perl -e 'print "<$_>\n" while <>' *
<bar
>
<foo
>

如果您有大量文件,就像您可能从 find 获得的那样,您应该使用 xargs 作为

但是,您不需要 findlscat 或您的 Perl 单行程序来 运行 您的脚本 .tag 当前目录下的文件。简单地做:

script.pl *.tag