例如,假设我运行下面的命令:
gawk -f AppendMapping.awk Reference.tsv TrueInput.tsv
假设文件的名称将发生变化。 同时通过第一个文件迭代,我想创建一个映射。
map[$16]=$18
同时,通过第二个文件迭代,我想使用的映射。
print $1, map[$2]
什么是实现这一目标的行为(即,不同的行为对每个输入文件)的最好方法?
例如,假设我运行下面的命令:
gawk -f AppendMapping.awk Reference.tsv TrueInput.tsv
假设文件的名称将发生变化。 同时通过第一个文件迭代,我想创建一个映射。
map[$16]=$18
同时,通过第二个文件迭代,我想使用的映射。
print $1, map[$2]
什么是实现这一目标的行为(即,不同的行为对每个输入文件)的最好方法?
正如你可能知道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]
}
GAWK版本4和提供高的特殊BEGINFILE
(和ENDFILE
)块以及通常的BEGIN
和END
块。 用它们来设置你改变你的代码的行为标志。
回想一下, 模式可以包括与变量进行比较 ,这样你就可以在你的标志的值直接选择patters。
该名男子网页显示:
对于每个输入文件,如果BEGINFILE规则存在,GAWK处理文件中的内容之前执行相关联的代码。 类似地,执行GAWK处理文件后ENDFILE相关联的代码。
这可能会为你工作:
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
因此,通过将FILENAME
与ARGV[n]
其中n
是在命令行中的第n个文件, awk
可以有条件地改变单个文件。
NB ARGV [0]将是awk
命令。