![объяснение кода awk](https://rvso.com/image/168819/%D0%BE%D0%B1%D1%8A%D1%8F%D1%81%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BA%D0%BE%D0%B4%D0%B0%20awk.png)
Мне дали код, который должен работать, но он не работает, и я пытаюсь понять, почему так. Я пытаюсь изучить 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
- что является законным, но редко применяется на практике.