Eu tenho um arquivo parecido com:
1
2 4 5 6
20
22
24 26 27
29 30 31 32 34 40 50 56 58
234 235 270 500
1234 1235 1236 1237
2300
Quero ter uma saída mostrando que há 4 linhas com 1 coluna e 3 linhas com 4 colunas e 1 linha com 3 colunas e 1 linha com 9 colunas. Então, a saída deve ser: linhas (colunas)
4 (1)
1 (3)
3 (4)
1 (9)
considerando que meus dados reais são enormes, alguma sugestão, por favor? Enquanto isso, quero que o número máximo da coluna seja mostrado na última linha (aqui 9) e um número mínimo de colunas seja mostrado na primeira linha da saída.
Responder1
Se você possui uma versão recente (> 4.0) do GNU awk:
gawk '
{a[NF]++}
END {
PROCINFO["sorted_in"]="@ind_num_asc";
for (i in a) printf "%d (%d)\n", a[i], i;
}' file
4 (1)
1 (3)
3 (4)
1 (9)
Responder2
ficar boquiabertoabordagem (usando asorti
função):
awk '{a[NF]++}END{ asorti(a,b); for(i in b) printf("%d (%d)\n",a[b[i]],b[i]) }' file
A saída:
4 (1)
1 (3)
3 (4)
1 (9)
asorti(a,b)
- classificar um array por índices
Responder3
Se você tratar cada célula da sua tabela como um espaço reservado para criar o resultado desejado, poderá classificar e contar linhas duplicadas para identificar quantas linhas têm a mesma quantidade de colunas.
a=$(sed 's/\([0-9]\+\)/1/g' file | sort | uniq -c)
dups=$( echo "$a" | cut -d' ' -f7 )
E depois disso você pode contar as palavras de cada linha para identificar quantas colunas há na linha.
words=$(echo "$a" | cut -d' ' -f8- | awk '{print NF}')
paste <(echo "$dups") <(echo "$words")
4 1
1 3
3 4
1 9
Responder4
A versão mais simples é
cat data.txt | awk '{counts[NF] += 1} END { for (row_count in counts) { printf "%d (%d)\n", counts[row_count], row_count; }'
Ele apenas usa NF
uma variável que fornece o número de campos na linha e atualiza o valor relevante associado a ela no dicionário. Então, no final do fluxo, ele apenas itera todas as chaves do dicionário e as imprime no formato solicitado.