объяснение кода awk

объяснение кода awk

Мне дали код, который должен работать, но он не работает, и я пытаюсь понять, почему так. Я пытаюсь изучить 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- что является законным, но редко применяется на практике.

Связанный контент