我已經得到了一些應該可以工作的程式碼,但它沒有,我試圖理解為什麼會這樣。由於這個原因,我正在嘗試學習 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
- 這是合法的,但在實踐中很少這樣做。