Comando Unix para verificar se existem duas linhas em um arquivo?

24

Existe um comando unix que pode verificar se existem 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

Vemos que a frase

This is sentence X

é repetido.

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

$ cat sentences.txt | thecommand
Line 1:This is sentence X
Line 4:This is sentence X
Código Azul
fonte

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 interior $(sort sentences.txt | uniq -d)lista cada linha que ocorre mais de uma vez. O externo grep -nFxprocura novamente correspondências sentences.txtexatas -xpara qualquer uma dessas linhas -Fe acrescenta o número da linha-n

Grebneke
fonte
Sua edição mal me impediu de postar exatamente a mesma resposta. 1
casey
Então a sintaxe $ (command) funciona como um tipo de substituição?
CodeBlue
2
@CodeBlue - sim. É chamado Comando Substituição
grebneke
8
sort sentences.txt | uniq -d | grep -nFxf - sentences.txtseria um pouco mais eficiente e evitaria possíveis arg list too longproblemas.
Stéphane Chazelas
10

Não é exatamente o que você deseja, mas você pode tentar combinar sorte 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:~$ 

2Aqui está 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
aularon
fonte
6

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

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

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 executa em conjunto em uso real. Se você fizer isso com frequência, poderá colocar o awkscript em um arquivo awk -fou, é claro, tudo em um script de shell. Como o mais simples, awkisso pode ser feito de maneira muito semelhante perl -n[a].

dave_thompson_085
fonte