Tentando ordenar duas listas de números e usando uniq para obter a interseção

3

Eu tenho um arquivo A e B, então usei o seguinte comando ...

(sort -n A B) | uniq -d

que deve me dar os números que ocorrem em ambos os arquivos.

1
2
2
3
4
5
11
11
12
31

Estes são os números que recebo de sort -n A B , mas quando eu canalizo para uniq -d , eu só obtenho 11 e não 2. O que estou fazendo errado?

    
por user2325601 25.05.2016 / 00:24

4 respostas

2

Como os comentários indicam, o problema parece ser branco ou retorno de carro. Qualquer um dos seguintes deve fazer o truque:

$ (sort -n A B) | sed -E 's/[^[:alnum:]]+$//' | uniq -d
$ (sort -n A B) | tr -d '\r ' | uniq -d

Alguns sabores do GNU sed usam -r para obter expressões regulares estendidas. tr é certamente mais simples, mas também mais brutal, na medida em que remove os caracteres, quer estejam ou não à direita.

    
por 25.05.2016 / 02:33
3

Como não é muito usado, mencionarei uma solução baseada em imagens:

comm -12 <(sort A) <(sort B)

Isso usa a substituição de processo <( ... ) para classificar os arquivos A e B e fornecê-los como entradas para comm , que então usa -12 para:

  -1     suppress column 1 (lines unique to FILE1) 
  -2     suppress column 2 (lines unique to FILE2)

... deixando apenas linhas comuns aos dois arquivos.

    
por 25.05.2016 / 03:46
2

Além do que don_crissti menciona sobre espaços à direita, você pode querer verificar o tipo de arquivo / estilo de nova linha também. A man page do uniq afirma que pode:

uniq - report or omit repeated lines

Se você tiver dito CRLF, ou seja, caracteres de nova linha no estilo do Windows em vez da LF esperada, poderá obter surpresas.

Você pode verificar rapidamente o tipo com:

file <filename>

Se você quiser remover qualquer sequência de linha final CRLF, poderá executar os arquivos de entrada através do dos2unix. O seguinte irá converter os caracteres da linha final.

dos2unix A
dos2unix B
    
por 25.05.2016 / 01:07
1

Dependendo do tamanho do arquivo, você pode usar apenas grep :

grep -Fxf A B

-f especifica um arquivo do qual obter uma lista de padrões.

-x significa corresponder apenas à linha inteira (não permitir a correspondência de uma parte de uma linha).

-F significa tratar os padrões como sequências fixas em vez de expressões regulares.

Se B for menor que A , você poderá obter resultados um pouco mais rápidos nomeando B como o arquivo padrão ( grep -Fxf B A ).

Você pode canalizar a saída para sort -u para obter uma lista ordenada das linhas distintas que ocorrem em cada arquivo:

grep -Fxf A B | sort -u

Claro que se o seu problema for o término da linha de retorno de carro, você deve usar dos2unix primeiro.

    
por 25.05.2016 / 03:24

Tags