Eu tenho um arquivo de texto que está estruturado da seguinte forma:
P,ABC,DEF
P,GHI,JKL
B,ABC,DEF
B,MNO,PQR
Eu quero obter uma contagem de quantas vezes uma linha aparece onde os campos 2 e 3 são os mesmos, preservando o campo 1. Então, a saída seria algo assim:
2,P,ABC,DEF
1,P,GHI,JKL
2,B,ABC,DEF
1,B,MNO,PQR
uniq -c
não funcionará (até onde eu sei) porque não pode separar por campo. sort -u -t, -k2,2 -k3,3
também não funcionará, pois não pode contar (até onde eu sei) e o comando conforme escrito simplesmente destruirá a terceira linha como uma duplicata, deixando a primeira.
No final das contas, o que preciso retornar são as linhas 2 e 4, pois os campos 2 e 3 combinados são únicos. Mas, preciso preservar o campo 1, pois se refere a qual conjunto de dados (no mundo real) os campos 2 e 3 se originam. Então, uma solução que retorne as linhas 2 e 4 é realmente o que eu preciso.
Assim, uma solução da seguinte forma também funciona:
P,GHI,JKL
B,MNO,PQR
Tomando seu
sort
comando, posso delegar-u
parauniq -u
, o que me permite usar a-f
opção deuniq
. Esta opção ignora o número determinado de campos à esquerda. Você quer ignorar o primeiro campo, então-f1
. Para que isso funcione, preciso traduzir cada,
um para um espaço em branco e voltar:Embora isso funcione com seu conjunto de dados de exemplo, ele falha quando há espaços em branco. Isso ocorre porque
uniq -f
reconhece um campo como[[:blank:]]*[^[:blank:]]*
. Se houver espaços em branco em seus dados reais, elesuniq
reconhecerão mais campos do que você deseja.Para superar isso, você precisa traduzir espaços em branco reais para não espaços em branco, executar
uniq
e traduzir de volta. Na localidade POSIX[:blank:]
inclui apenas o espaço e o caractere de tabulação; em outras localidades, pode incluir mais.O comando a seguir converte temporariamente espaços em caracteres DC1 (controle de dispositivo 1, octal
021
) e tabulações em DC2 (controle de dispositivo 2, octal022
):Deve funcionar, se apenas os dados não contiverem DC1 nem DC2.
Mesmo que você
tr
não suporte caracteres multibyte , a tradução não interferirá nos caracteres multibyte de UTF-8 porque o bit mais significativo em cada byte em um caractere multibyte em UTF-8 é sempre1
, enquanto para DC1 ou DC2 é0
.