Awk-Code-Erklärung

Awk-Code-Erklärung

Ich habe Code erhalten, der eigentlich funktionieren sollte, aber nicht funktioniert. Ich versuche herauszufinden, warum das so ist. Aus diesem Grund versuche ich, Bash und Awk zu lernen, aber es ist ziemlich verwirrend für mich. Wenn mir jemand helfen könnte, diesen Awk-Code zu verstehen, wäre ich sehr glücklich.

cvgMids.txtenthält viele Zeilen des folgenden Formats

<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> .
  • Was soll das? „ BEGIN{i=0;}Ich sehe in keiner der folgenden Zeilen, dass die Variable i verwendet wird.“

  • Wofür ist <(cat cvgMids.txt) <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txtdas? Ich verstehe, dass Sie die Dateien am Ende von awk ablegen, aber all diese Klammern usw. verwirren mich.

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

Antwort1

Das Snippet scheint die Zeilen mit dem unkomprimierten Inhalt von auszugeben, freebase-rdf-latest.gzderen erstes durch Leerzeichen getrenntes Feld $1mit einem der ersten durch Leerzeichen getrennten Felder von übereinstimmt cvgMids.txt. Es könnte jedoch auch einfacher geschrieben werden.

Insbesondere:

  • wie Sie bemerkt haben, iwird es nirgends verwendet, daher BEGINkann die Sperre aufgehoben werden

  • der Ablauf

    if($1 in a) next;
    a[$1] = $1;
    next
    

    könnte reduziert werden auf

    a[$1];
    next
    

    (das ArrayWertewerden nie verwendet, nur ihre Indizes, und es ist mit ziemlicher Sicherheit genauso effizient, den Index mehrmals neu zuzuweisen, wie ihn zu testen und bedingt zuzuweisen)

  • in der Regel-Aktion

    FNR<NR {
        if($1 in a) {print $0;}}
    

    Sie brauchen es nicht wirklich, FNR<NRda Sie den Fall bereits behandelt haben FNR==NRund FNR>NRes nicht passieren wird 1 . Außerdem {print $0;}ist dies die Standardaktion. Es wäre also idiomatischer zu schreiben

    $1 in a 
    
  • <(cat cvgMids.txt)und <(gzip -dc freebase-rdf-latest.gz)sind ShellProzesssubstitutionenFunktionell ist das erste äquivalent zu cvgMids.txt(es ist sowohl einSinnloser Einsatz einer Katzeund eine nutzlose Verwendung der Umleitung). Vielleicht wurde es aus ästhetischen Gründen verwendet.

Wenn wir alles zusammenfügen, erhalten wir

awk 'FNR == NR {a[$1]; next} $1 in a' cvgMids.txt <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txt

Wenn das Original jedoch nicht funktioniert, funktioniert auch die vereinfachte Version nicht.


1 , sofern Ihr Code nicht FNRund/oder geändert wird NR– was zulässig ist, in der Praxis jedoch selten getan wird.

verwandte Informationen