Tengo mis referencias como un archivo de texto con una larga lista de entradas y cada una tiene dos (o más) campos.
La primera columna es la url de la referencia; la segunda columna es el título que puede variar un poco dependiendo de cómo se realizó la entrada. Lo mismo para el tercer campo que puede o no estar presente.
Quiero identificar pero no eliminar entradas que tienen el primer campo (URL de referencia) idéntico. Lo sé, sort -k1,1 -u
pero eso eliminará automáticamente (de forma no interactiva) todos menos el primer golpe. ¿Hay alguna manera de avisarme para que pueda elegir cuál conservar?
En el extracto a continuación de tres líneas que tienen el mismo primer campo ( http://unix.stackexchange.com/questions/49569/
), me gustaría mantener la línea 2 porque tiene etiquetas adicionales (ordenar, CLI) y eliminar las líneas # 1 y # 3:
http://unix.stackexchange.com/questions/49569/ unique-lines-based-on-the-first-field
http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field sort, CLI
http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field
¿Existe un programa para ayudar a identificar tales "duplicados"? Entonces, ¿puedo limpiar manualmente eliminando personalmente las líneas 1 y 3?
fuente
Respuestas:
Si entiendo tu pregunta, creo que necesitas algo como:
o:
¿Dónde
file.txt
está interesado su archivo que contiene datos sobre usted?En la salida verá el número de líneas y líneas donde se encuentra el primer campo dos o más veces.
fuente
cut -d " " -f1 file.txt | uniq -d
me da buena salida.Este es un problema clásico que se puede resolver con el
uniq
comando.uniq
puede detectar líneas consecutivas duplicadas y eliminar duplicados (-u
,--unique
) o mantener solo duplicados (-d
,--repeated
).Dado que el orden de las líneas duplicadas no es importante para usted, primero debe ordenarlo. Luego, use
uniq
para imprimir solo líneas únicas:También hay una opción
-c
(--count
) que imprime el número de duplicados para la-d
opción. Vea la página del manual deuniq
para más detalles.Si realmente no le importan las partes después del primer campo, puede usar el siguiente comando para buscar claves duplicadas e imprimir cada número de línea (agregue otro
| sort -n
para ordenar la salida por línea):Como desea ver líneas duplicadas (usando el primer campo como clave), no puede usar directamente
uniq
. El problema que dificulta la automatización es que las partes del título varían, pero un programa no puede determinar automáticamente qué título debe considerarse el último.Aquí hay un script AWK (guárdelo
script.awk
) que toma su archivo de texto como entrada e imprime todas las líneas duplicadas para que pueda decidir cuál eliminar. (awk -f script.awk yourfile.txt
)fuente
-w
(--check-chars
) para limitar a un número fijo de caracteres, pero al ver su ejemplo, tiene primeros campos variables. Comouniq
no admite la selección de campos, debe utilizar una solución alternativa. Incluiré un ejemplo de AWK ya que es más fácil.-w
pero la longitud del primer campo es variable :(Si leo esto correctamente, todo lo que necesitas es algo como
Eso imprimirá el número de la línea que contiene el engaño y la línea misma. Por ejemplo, usando este archivo:
Producirá esta salida:
Para imprimir solo el número de la línea, puede hacer
Y para imprimir solo la línea:
Explicación:
El
awk
script solo imprime el primer campo separado del espacio del archivo. Use$N
para imprimir el enésimo campo.sort
lo ordena yuniq -c
cuenta las ocurrencias de cada línea.Esto luego se pasa al
while
bucle que guarda el número de ocurrencias como$num
y la línea como$dupe
y si$num
es mayor que uno (por lo que se duplica al menos una vez) buscará el archivo para esa línea, utilizando-n
para imprimir el número de línea. El--
le dicegrep
que lo que sigue no es una opción de línea de comando, útil para cuándo$dupe
puede comenzar-
.fuente
Sin duda, el más detallado de la lista, probablemente podría ser más corto:
da en un archivo de texto como:
una salida como:
Una vez que haya elegido las líneas para eliminar:
fuente
Ver lo siguiente ordenado
file.txt
:Debido a que la lista es corta, puedo ver (después de ordenar) que hay tres conjuntos de duplicados.
Entonces, por ejemplo, puedo elegir mantener:
más bien que
Pero para una lista más larga esto será difícil. Basado en las dos respuestas, una que sugiere
uniq
y la otra que sugierecut
, encuentro que este comando me da el resultado que me gustaría:fuente
cut
. Si está realizando un trabajo de eliminación de duplicados, los números de línea pueden ser muy útiles. Para imprimir todos los duplicados, use la-D
opción en lugar de-d
.for dup in $(cut -d " " -f1 file.txt | uniq -d); do grep -n $dup file.txt; done
como en mi respuesta. Le dará una mejor vista previa de lo que le interesa.Ella es como lo resolví:
file_with_duplicates:
Archivo ordenado y deducido por las columnas 1 y 2:
Archivo ordenado solo por las columnas 1 y 2:
Mostrar solo la diferencia:
fuente