Perl中文件的行号

时间:2012-09-12 09:05:28

标签: perl

awk中,如果我将多个文件作为参数提供给awk,则有两个特殊变量:

NR =与所有文件中的所有行对应的行号。

FNR =当前文件的行号。

我知道在Perl中,$.对应NR(所有文件中行之间的当前行)。

在Perl中是否还有与FNR AWK类似的内容?

假设我有一些命令行:

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 个答案:

答案 0 :(得分:6)

实际上,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

答案 1 :(得分:3)

Perl中没有这样的变量。但是你应该学习eof以便能够写出像

这样的东西
perl -ne 'print join ":", $. + $sum, $., "\n"; $sum += $., $.=0  if eof;' *txt

答案 2 :(得分:0)

我发现这种情况是使用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正则表达式,我只会使用awkgit grep -P。但是,如果您要处理的是一个相当复杂的正则表达式,或者需要其他perl功能,那将无法正常工作……并且该问题的正确答案进一步使已经很可能是复杂的perl单行代码。

所以我只使用以下内容:

£ 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中解决它却几乎总是需要一个实际的脚本与单线。在大多数情况下, 对于系统范围的搜索是不可接受的。