检测单行中的第一个或第二个文件

时间:2014-08-17 12:25:09

标签: perl

在AWK中,对于在两个文件上运行的脚本,通常会看到这种结构:

awk 'NR==FNR { print "first file"; next } { print "second file" }' file1 file2

使用以下事实:定义了两个变量:FNR,它是当前文件中的行号,NR是全局计数(相当于Perl' s {{ 1}})。

在Perl中有类似的东西吗?我想我可以使用$.和一个计数器变量:

eof

这有效,但感觉我可能会遗漏一些东西。


为了提供一些上下文,我写了this answer,其中我手动定义了一个哈希,但是,我想从第一个文件中的值填充哈希值,然后在第二个文件上进行替换。我怀疑在Perl中有一种巧妙的,惯用的方式。

2 个答案:

答案 0 :(得分:2)

看起来你的目标是使用相同的循环来读取两个文件,并在循环内部选择如何处理数据。我会避免这个想法,因为你在同一段代码中隐藏了两个不同的进程,使得它不清楚发生了什么。

但是,在只有两个文件的情况下,您可以将当前文件与@ARGV的第一个元素进行比较,就像这样

perl -nE 'if ($ARGV eq $ARGV[0]) { say "first file" } else { say "second file" }' file1 file2

忘记我热爱的单行程序,我只是明确地打开$ARGV[0]$ARGV[1]。也许像这样命名它们

use strict;
use warnings;
use 5.010;
use autodie;

my ($definitions, $data) = @ARGV;

open my $fh, '<', $definitions;
while (<$fh>) {
   # Build hash
}

open $fh, '<', $data;
while (<$fh>) {
   # Process file
}

但是如果你想利用自动开放设施那么你可以像这样混淆@ARGV

use strict;
use warnings;

my ($definitions, $data) = @ARGV;

@ARGV = ($definitions);
while (<>) {
   # Build hash
}

@ARGV = ($data);
while (<>) {
   # Process file
}

答案 1 :(得分:2)

不幸的是,perl没有类似的NR==FNR构造来区分两个文件。你可以做的是使用BEGIN块处理一个文件和主体来处理另一个。

例如,要使用以下内容处理文件:

<强>的map.txt

a=apple
b=ball
c=cat
d=dog

<强> alpha.txt

f
a
b
d

你可以这样做:

perl -lne'
BEGIN { 
    $x = pop; 
    %h = map { chomp; ($k,$v) = split /=/; $k => $v } <>; 
    @ARGV = $x 
}
print join ":", $_, $h{$_} //= "Not Found"
' map.txt alpha.txt
f:Not Found
a:apple
b:ball
d:dog

<强>更新

我给出了一个非常简单的例子,现在当我看到它时,我只能说TIMTOWDI,因为你能做到:

perl -F'=' -lane'
    if (@F == 2) { $h{$F[0]} = $F[1]; next }
    print join ":", $_, $h{$_} //= "Not Found"
' map.txt alpha.txt
f:Not Found
a:apple
b:ball
d:dog

但是,我可以肯定地说,NR==FNR没有perl构造,您可以根据文件以各种不同的方式处理它们。