¿Comando Unix para verificar si dos líneas en un archivo son iguales?

24

¿Hay un comando unix que pueda verificar si dos líneas en un archivo son iguales?

Por ejemplo, considere un archivo 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 la oración

This is sentence X

se repite.

¿Hay algún comando que pueda detectar esto rápidamente, de modo que tal vez pueda ejecutarlo así?

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

Respuestas:

40

Aquí hay una forma de obtener el resultado exacto que está buscando:

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

Explicación:

El interior $(sort sentences.txt | uniq -d)enumera cada línea que ocurre más de una vez. El exterior grep -nFxbusca nuevamente coincidencias sentences.txtexactas -xcon cualquiera de estas líneas -Fy antepone su número de línea-n

grebneke
fuente
Su edición apenas me superó al publicar exactamente la misma respuesta. +1
casey
Entonces, ¿la sintaxis $ (comando) funciona como una especie de reemplazo?
CodeBlue
2
@CodeBlue: sí. Se llama Sustitución de comando
grebneke
8
sort sentences.txt | uniq -d | grep -nFxf - sentences.txtsería un poco más eficiente y evitaría posibles arg list too longproblemas.
Stéphane Chazelas
10

No es exactamente lo que quieres, pero puedes intentar combinar sorty 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:~$ 

2Aquí está el número de duplicaciones encontradas para la línea, desde man uniq:

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

   -d, --repeated
          only print duplicate lines
aularon
fuente
6

SI el contenido del archivo cabe en la memoria awk es bueno para esto. El one-liner estándar en comp.lang.awk (no puedo buscar una instancia de esta máquina pero hay varias cada mes) para detectar que hay una duplicación awk 'n[$0]++'que cuenta las ocurrencias de cada valor de línea e imprime cualquier ocurrencia (s) que no sea el primero, porque la acción predeterminada es print $0.

Para mostrar todas las ocurrencias, incluida la primera, en su formato, pero posiblemente en un orden mixto cuando se duplica más de un valor, se vuelve un poco más 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} '

Se muestra en varias líneas para mayor claridad, generalmente se ejecutan juntos en uso real. Si hace esto con frecuencia, puede colocar el awkscript en un archivo awk -fo, por supuesto, todo en un script de shell. Como la mayoría simple, awkesto se puede hacer de manera muy similar con perl -n[a].

dave_thompson_085
fuente