Problema ao extrair dados do arquivo usando awk

Problema ao extrair dados do arquivo usando awk

Eu tenho um arquivo de dados grande e quero dividi-lo em arquivos menores com base nos valores da coluna 1. Por exemplo, a coluna 1 tem números de 1 a 10 dez vezes para formar 100 linhas e quero todas as linhas com números '1' ou '2 ' ou '3' etc em seu próprio arquivo (de preferência sem classificação). Além disso, não quero executar o comando 10 vezes, então gostaria que ele estivesse em loop.

Meus arquivos ficam assim:

  • text.txt

    insira a descrição da imagem aqui

  • ID.txt

    1
    2
    3
    4
    

O comando que tentei:

cat ID.txt | while read line; do awk '$1 == ${line}' test.txt >$line.txt;done

Então, para resumir, quero ler o valor do arquivo ID.txt, por exemplo, '1' e, em seguida, extrair todas as linhas com '1' na primeira linha e colocá-lo em um arquivo chamado 1.txt, então ele itera para 2 e então 3 depois 4 etc.

Mas de alguma forma a parte '$1 == ${line}' eu acho que não está funcionando

Responder1

Você está procurando a -vopção de awk:

   -v var=val
   --assign var=val
          Assign the value val to the variable var,  before  execution  of
          the  program  begins.  Such variable values are available to the
          BEGIN rule of an AWK program.

Algo assim:

cat ID.txt | 
    while read line; do awk -vline="$line" '$1 == l' test.txt >"$line".txt;done

O que seria melhor expresso como (evitando o uso inútil de cat):

while read line; do 
    awk -vline="$line" '$1 == l' test.txt >"$line".txt;
done < ID.txt

No entanto, isso é muito lento e ineficiente. Você está executando o awkcomando inteiro test.txtpara cada linha do arquivo ID.txt. Por que não apenas ler ID.txte awkimprimir as linhas correspondentes:

awk 'NR==FNR{a[$1]++; next} ($1 in a){print >> $1".txt"}' ID.txt test.txt 

O acima salva o primeiro campo ID.txtdo array a. NRe FNRsão awkvariáveis ​​especiais que significam "a linha atual do fluxo de entrada" e "a linha atual do arquivo atual". Os dois só serão iguais quando o primeiro arquivo estiver sendo lido. Portanto, NR==FNR{a[$1]++; next}só será executado nas linhas do primeiro arquivo. A segunda parte não será executada porque nextindica awkpara pular para a próxima linha.

A segunda parte verifica se o primeiro campo da linha atual (lembre-se, isso só é executado no segundo arquivo) existe no array a(o que significa que estava em ID.txt) e, se existir, imprime a linha em um arquivo chamado "campo1. TXT"

informação relacionada