Comando Unix para verificar se duas linhas em um arquivo são iguais?

24

Existe um comando unix que pode verificar se duas linhas em um arquivo são iguais?

Por exemplo Considere um arquivo sentences.txt

This is sentence X
This is sentence Y
This is sentence Z
This is sentence X
This is sentence A
This is sentence B

Nós vemos que a sentença

This is sentence X

é repetido.

Existe algum comando que possa detectar isso rapidamente, para que eu possa, talvez, executá-lo assim -

$ cat sentences.txt | thecommand
Line 1:This is sentence X
Line 4:This is sentence X
    
por CodeBlue 05.02.2014 / 19:17

3 respostas

40

Aqui está uma maneira de obter a saída exata que você está procurando:

$ grep -nFx "$(sort sentences.txt | uniq -d)" sentences.txt 
1:This is sentence X
4:This is sentence X

Explicação:

O $(sort sentences.txt | uniq -d) interno lista cada linha que ocorre mais de uma vez. O% outer grep -nFx aparece novamente em sentences.txt para exatamente -x corresponde a qualquer uma dessas linhas -F e preenche o número de sua linha -n

    
por 05.02.2014 / 19:20
10

Não é exatamente o que você quer, mas você pode tentar combinar sort e uniq -c -d :

aularon@aularon-laptop:~$ cat input
This is sentence X
This is sentence Y
This is sentence Z
This is sentence X
This is sentence A
This is sentence B

aularon@aularon-laptop:~$ sort input | uniq -cd
      2 This is sentence X
aularon@aularon-laptop:~$ 

2 aqui é o número de duplicações encontradas para a linha, de man uniq :

   -c, --count
          prefix lines by the number of occurrences

   -d, --repeated
          only print duplicate lines
    
por 05.02.2014 / 19:22
6

SE o conteúdo do arquivo couber na memória awk é bom para isso. O one-liner padrão em comp.lang.awk (não consigo pesquisar uma instância dessa máquina, mas há vários a cada mês) para detectar que há duplicação é awk 'n[$0]++' , que conta as ocorrências de cada valor de linha e imprime qualquer ocorrência (s) diferente do primeiro, porque a ação padrão é print $0 .

Para mostrar todas as ocorrências, incluindo a primeira, no seu formato, mas possivelmente em ordem mista, quando mais de um valor é duplicado, fica um pouco mais meticuloso:

awk <sentences.txt ' !($0 in n) {n[$0]=NR;next} \
    n[$0] {n[$0]=0; print "Line "n[$0]":"$0} \
    {print "Line "NR":"$0} '

Mostrado em várias linhas para maior clareza, você geralmente é executado em conjunto no uso real. Se você fizer isso com frequência, poderá colocar o script awk em um arquivo com awk -f ou, claro, a coisa toda em um script de shell. Como a maioria dos awk , isso pode ser feito de forma muito semelhante com perl -n[a] .

    
por 05.02.2014 / 23:43