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:
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 -v
opçã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 awk
comando inteiro test.txt
para cada linha do arquivo ID.txt
. Por que não apenas ler ID.txt
e awk
imprimir 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.txt
do array a
. NR
e FNR
são awk
variá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 next
indica awk
para 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"