我遇到一个问题,我的perl脚本在输入管道输出时会失败,但是当我单独列出所有文件名时,它会正常工作。
作为参考,使用while(<>)读取perl脚本的输入。
示例:
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
所有这些都以同样的方式失败。这就像脚本没有输入参数传递,程序就完成了。
答案 0 :(得分:3)
空文件句柄
<>
是特殊的[...]来自<>
的输入来自标准输入,或来自命令行中列出的每个文件。以下是它的工作原理:第一次评估<>
时,会检查@ARGV
数组,如果它是空的,则$ARGV[0]
设置为-
,打开时为您提供标准输入。然后将@ARGV
数组作为文件名列表处理。
您没有将任何命令行参数传递给Perl脚本,因此您输入的所有内容都会被读入STDIN
而不是被视为文件名:
$ echo foo > foo.txt
$ echo bar > bar.txt
$ ls | perl -e 'print "<$_>\n" while <>'
<bar.txt
>
<foo.txt
>
请注意,实际上并未读取foo.txt
和bar.txt
文件;我们得到的只是文件名。如果要打开和读取文件,则必须将它们作为命令行参数传递或明确设置@ARGV
:
$ perl -e 'print "<$_>\n" while <>' *
<bar
>
<foo
>
如果您有大量文件,例如您可能来自find
,则应使用xargs
作为Dyno Hongjun Fu suggested。
但是,您不需要find
,ls
,cat
或Perl one-liner在所有.tag
文件中运行您的脚本当前目录。只需:
script.pl *.tag
答案 1 :(得分:1)
你需要xargs,例如
find ./ -type f -name "*.tag" | xargs -i script.pl {}
什么是chomp?