是否可以将第一个和第二个输入文件的不同行为设置为awk?

时间:2012-05-21 19:05:00

标签: awk gawk

例如,假设我运行以下命令:

gawk -f AppendMapping.awk Reference.tsv TrueInput.tsv

假设文件名称将更改。 在迭代第一个文件时,我想创建一个映射。

map[$16]=$18

在迭代第二个文件时,我想使用映射。

print $1, map[$2]

实现此行为的最佳方法是什么(即每个输入文件的行为不同)?

3 个答案:

答案 0 :(得分:4)

您可能知道NR存储当前行号;你可能知道也可能不知道,它是累积的 - 它不会在文件之间重置。另一方面,FNR特定于文件,因此您可以使用这两个来查看您是否在第一个文件中(超过您需要保留自己的计数器的第二个文件)。

# In case you want to keep track of the file number
FNR == 1 { fileno++ }*emphasized text*

NR == FNR {
    # First file
}
NR != FNR {
    # Second or later file
}

您还可以使用getline块中的BEGIN手动循环播放。

BEGIN {
    file = ARGV[1]
    while(getline < file) {
        # Process line
    }
    delete ARGV[1]
}

答案 1 :(得分:1)

Gawk版本4和高版本提供了特殊的BEGINFILE(和ENDFILE)块以及通常的BEGINEND块。使用它们来设置改变代码行为的标志。

回想一下patterns can include comparisons with variables,这样就可以直接根据标志的值选择模式。

手册页说:

  

对于每个输入文件,如果存在BEGINFILE规则,gawk会在处理之前执行相关代码          文件的内容。类似地,gawk在处理之后执行与ENDFILE相关联的代码          文件。

答案 2 :(得分:0)

这可能对您有用:

seq 5 >/tmp/a
seq 100 105 >/tmp/b
awk 'FILENAME==ARGV[1]{print FILENAME,$0};FILENAME==ARGV[2]{print $0,FILENAME}' /tmp/{a,b}
/tmp/a 1
/tmp/a 2
/tmp/a 3
/tmp/a 4
/tmp/a 5
100 /tmp/b
101 /tmp/b
102 /tmp/b
103 /tmp/b
104 /tmp/b
105 /tmp/b

因此,将FILENAMEARGV[n]组合在一起n是命令行中的第n个文件,awk可以有条件地更改单个文件。

N.B。 ARGV [0]将是awk命令。