![explicação do código awk](https://rvso.com/image/168819/explica%C3%A7%C3%A3o%20do%20c%C3%B3digo%20awk.png)
Recebi um código que deveria estar funcionando, mas não funciona, e estou tentando entender por que isso acontece. Estou tentando aprender bash e awk por esse motivo, mas é bastante confuso para mim. Se alguém pudesse me ajudar a entender esse código awk eu ficaria muito feliz.
cvgMids.txt
contém muitas linhas do seguinte 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> .
Qual é o sentido de
BEGIN{i=0;}
não ver a variável i sendo usada em nenhuma das linhas a seguir.Para que é
<(cat cvgMids.txt) <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txt
? Entendo que você colocou os arquivos no final do awk, mas está confuso para mim com todos esses parênteses 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
Responder1
O que o snippet parece fazer é gerar as linhas do conteúdo descompactado freebase-rdf-latest.gz
cujo primeiro campo delimitado por espaço em branco $1
corresponde a qualquer um dos primeiros campos delimitados por espaço em branco de cvgMids.txt
. No entanto, poderia ser escrito de forma mais simples.
Em particular:
como você observou,
i
não é usado em nenhum lugar, então oBEGIN
bloqueio pode ser eliminadoa sequência
if($1 in a) next; a[$1] = $1; next
poderia ser reduzido a
a[$1]; next
(a matrizvaloresnunca são usados, apenas seus índices e é quase certamente tão eficiente reatribuir o índice várias vezes quanto testá-lo e atribuí-lo condicionalmente)
na regra-ação
FNR<NR { if($1 in a) {print $0;}}
você realmente não precisa,
FNR<NR
pois já tratou do casoFNR==NR
eFNR>NR
isso não vai acontecer 1 . Além disso,{print $0;}
é a ação padrão. Então seria mais idiomático escrever$1 in a
<(cat cvgMids.txt)
e<(gzip -dc freebase-rdf-latest.gz)
são cascasubstituições de processo. Funcionalmente, o primeiro é equivalente acvgMids.txt
(é ao mesmo tempo umUso inútil de gatoe um uso inútil de redirecionamento). Talvez tenha sido usado por razões estéticas.
Juntando tudo, obtemos
awk 'FNR == NR {a[$1]; next} $1 in a' cvgMids.txt <(gzip -dc freebase-rdf-latest.gz) > cvg_predicates.txt
Porém, se o original não funcionar, a versão simplificada também não funcionará.
1, a menos que seu código seja modificado FNR
e/ou NR
- o que é legal, mas raramente feito na prática.