我已经得到了一些应该可以工作的代码,但它没有,我试图理解为什么会这样。由于这个原因,我正在尝试学习 bash 和 awk,但这对我来说很困惑。如果有人能帮助我理解这段 awk 代码,我会非常高兴。
cvgMids.txt
包含许多以下格式的行
<http://rdf.freebase.com/ns/g.11b74p1stp> <http://rdf.freebase.com/ns/type.object.type> <http://rdf.freebase.com/ns/cvg.video_game_soundtrack> .
<http://rdf.freebase.com/ns/g.11bc4msmrn> <http://rdf.freebase.com/ns/type.object.type> <http://rdf.freebase.com/ns/cvg.cvg_developer> .
<http://rdf.freebase.com/ns/g.11bxxz28q6> <http://rdf.freebase.com/ns/type.object.type> <http://rdf.freebase.com/ns/cvg.computer_videogame> .
BEGIN{i=0;}
我没有看到在以下任何行中使用变量 i的意义是什么。是
<(cat cvgMids.txt) <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txt
为了什么?我知道你把文件放在 awk 的末尾,但所有这些括号等让我感到困惑。
awk 'BEGIN{i=0;}
FNR == NR {
if($1 in a) next;
a[$1] = $1;
next
}
FNR<NR {
if($1 in a) {print $0;}}' <(cat cvgMids.txt) <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txt
答案1
该代码片段的作用是输出未压缩内容中的行,freebase-rdf-latest.gz
其第一个空格分隔字段$1
与 中的任何第一个空格分隔字段相匹配cvgMids.txt
。不过还可以写得更简单。
尤其:
正如您所指出的,
i
没有在任何地方使用,因此该BEGIN
块可能会被消除序列
if($1 in a) next; a[$1] = $1; next
可以减少到
a[$1]; next
(数组的价值观从未使用过,仅使用其索引,并且几乎可以肯定多次重新分配索引与测试和有条件分配它一样有效)
在规则-行动中
FNR<NR { if($1 in a) {print $0;}}
你其实并不需要,
FNR<NR
因为你已经处理过这个案子FNR==NR
并且FNR>NR
不会发生1。另外,{print $0;}
这是默认操作。所以这样写会更惯用$1 in a
<(cat cvgMids.txt)
并且<(gzip -dc freebase-rdf-latest.gz)
是外壳流程替代。从功能上讲,第一个相当于cvgMids.txt
(它都是猫的无用用途以及无用的重定向)。也许它是出于审美原因而使用的。
把它们放在一起,我们得到
awk 'FNR == NR {a[$1]; next} $1 in a' cvgMids.txt <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txt
但是,如果原始版本不起作用,那么简化版本也将不起作用。
1除非你的代码修改FNR
和/或NR
- 这是合法的,但在实践中很少这样做。