explicación del código awk

explicación del código awk

Me dieron un código que se supone que funciona, pero no funciona, y estoy tratando de entender por qué. Estoy intentando aprender bash y awk por ese motivo, pero me resulta bastante confuso. Si alguien pudiera ayudarme a comprender este código awk, estaría muy feliz.

cvgMids.txtcontiene muchas líneas del siguiente formato

<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> .
  • ¿Cuál es el punto de que BEGIN{i=0;}no veo que se utilice la variable i en ninguna de las siguientes líneas?

  • ¿Que es <(cat cvgMids.txt) <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txtpor? Entiendo que pusiste los archivos al final de awk pero me confunde con todos estos paréntesis, etc.

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

Respuesta1

Lo que parece hacer el fragmento es generar las líneas del contenido sin comprimir freebase-rdf-latest.gzcuyo primer campo delimitado por espacios en blanco $1coincide con cualquiera de los primeros campos delimitados por espacios en blanco de cvgMids.txt. Sin embargo, podría escribirse de forma más sencilla.

En particular:

  • como notó, ino se usa en ninguna parte, por lo que el BEGINbloqueo puede eliminarse

  • la secuencia

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

    podría reducirse a

    a[$1];
    next
    

    (la matrizvaloresnunca se utilizan, solo sus índices y es casi seguro que es tan eficiente reasignar el índice varias veces como probarlo y asignarlo condicionalmente)

  • en la regla-acción

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

    realmente no lo necesita FNR<NRporque ya se ha ocupado del caso FNR==NRy FNR>NRno va a suceder 1 . Además, {print $0;}es la acción predeterminada. Entonces sería más idiomático escribir

    $1 in a 
    
  • <(cat cvgMids.txt)y <(gzip -dc freebase-rdf-latest.gz)son conchasustituciones de procesos. Funcionalmente, el primero es equivalente a cvgMids.txt(es a la vez unUso inútil del gatoy un uso inútil de la redirección). Quizás se utilizó por motivos estéticos.

Poniéndolo todo junto, obtenemos

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

Sin embargo, si el original no funciona, la versión simplificada tampoco funcionará.


1 a menos que su código modifique FNRy/o NR, lo cual es legal, pero rara vez se hace en la práctica.

información relacionada