Номер строки файла в Perl
на awk
Если я дам более одного файла в качестве аргумента awk
, есть две специальные переменные:
NR
=номер строки, соответствующий всем строкам во всех файлах.
FNR
=номер строки текущего файла.
Я знаю, что в Perl, $.
соответствует NR
(текущая строка среди строк во всех файлах).
есть ли что-нибудь сравнимое с FNR
AWK в Perl тоже?
perl -pe 'print filename,<something special which hold the current file's line number>' *.txt
это должно дать мне выходной, как:
file1.txt 1
file1.txt 2
file2.txt 1
3 ответов
в Perl нет такой переменной. Но вы должны учиться!--2-->eof уметь писать что-то вроде
perl -ne 'print join ":", $. + $sum, $., "\n"; $sum += $., $.=0 if eof;' *txt
на самом деле eof
документация показывает способ сделать это:
# reset line numbering on each input file
while (<>) {
next if /^\s*#/; # skip comments
print "$.\t$_";
} continue {
close ARGV if eof; # Not eof()!
}
пример однострочной печати первой строки всех файлов:
$ perl -ne 'print "$ARGV : $_" if $. == 1; } continue { close ARGV if eof;' *txt
Я считаю, что эта ситуация является очень большим недостатком использования Perl. Хотя этот ответ является неоптимальным, с точки зрения производительности и подходит только для ситуаций, связанных с xargs
, Я обычно находил его обходным путем, который я использую 95% времени. Итак, сценарий проблемы:
£ git ls-files -z | xargs -0 perl -ne 'print "$ARGV:$.\t$_" if /#define oom/'
file.h:85806 #define oom() exit(-1)
этот номер строки, очевидно, не правильный, и вы, очевидно, получите такое же поведение с find
конечно, с этим регулярным выражением или другими более простыми регулярными выражениями perl я бы просто использовал awk
или git grep -P
. Однако если вы имеете дело с довольно сложным регулярным выражением или нуждаетесь в других функциях perl, которые не будут работать...и правильно ответы на этот вопрос еще больше усложняют то, что уже, вероятно, будет сложным Perl one-liner.
поэтому я просто использую следующее:
£ git ls-files -z | xargs -0 -n1 perl -ne 'print "$ARGV:$.\t$_" if /#define oom/'
file.h:43 #define oom() exit(-1)
на -n1
аргумент xargs заставляет xargs запускать процесс perl для каждого файла, что приводит к правильным номерам строк. Ты смотришь на очень значительное влияние на производительность, но я нашел его приемлемым для очень больших проектов с миллионами строк кода против его решения в perl, что я нахожу почти всегда требует фактического сценария против однострочного. Это не приемлемо для системы поиска в подавляющем большинстве случаев.