2015-03-13 2 views
0

У меня возникла проблема, когда мой скрипт perl завершится неудачей при наличии входного потока, но отлично работает, когда я просто перечисляю все имена файлов по отдельности.Передача списка файлов в perl-скрипт через трубку

Для справки, ввод скрипта 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 

Я также протестировали демпинг его в текстовый файл и catting, что в Perl:

cat files.text | script.pl 

Все из них не одинаково. Это похоже на то, что скрипт не передал входных аргументов, и программа просто заканчивается.

ответ

3

От perldoc perlop:

Нулевая указатель_на_файл <> специальный [...] Входной сигнал от <> поставляется либо со стандартного ввода, или из каждого файла, указанного в командной строке. Вот как это работает: в первый раз оценивается <>, проверяется массив @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 Однострочник для запуска сценария на всех .tag файлов в текущем каталоге. Просто выполните:

script.pl *.tag 
+0

Ничего себе проще, чем я думал. Спасибо за полный ответ! – jbord39

1

Вам нужны xargs, например.

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

Что такое chomp?

+0

chomp удаляет заднюю новую линию. это была моя попытка убедиться, что форматирование было точно таким же, как моя версия (без новой строки в конце) – jbord39

+0

в основном, xargs решит вашу проблему. вы также можете попробовать удалить -i, '' 'find ./ -type f -name" * .tag "| скрипт xargs.pl''', то он будет кормить скрипту.pl в партии. –

Смежные вопросы