Pregunta

Para utilizar el comando uniq, primero debe ordenar su archivo.

Pero en el archivo que tengo, el orden de la información es importante, por lo tanto, ¿cómo puedo mantener el formato original del archivo pero aún así eliminar el contenido duplicado?

¿Fue útil?

Solución

Otra versión awk:

awk '!_[<*>]++' infile

Otros consejos

Este awk mantiene la primera aparición. Mismo algoritmo que usan otras respuestas:

awk '!(
sort file | uniq -d | awk '
   FNR == NR { dups[<*>] }
   FNR != NR && (!(<*> in dups) || !lines[<*>]++)
' - file
in lines) { print <*>; lines[<*>]; }'

Aquí hay uno que solo necesita almacenar líneas duplicadas (a diferencia de todas las líneas) usando awk :

<*>

También existe el " número de línea, doble ordenación " método.

 nl -n ln | sort -u -k 2| sort -k 1n | cut -f 2-

Puede ejecutar uniq -d en la versión ordenada del archivo para encontrar las líneas duplicadas, luego ejecutar un script que diga:

if this_line is in duplicate_lines {
    if not i_have_seen[this_line] {
        output this_line
        i_have_seen[this_line] = true
    }
} else {
    output this_line
}

Usando solo uniq y grep:

Crear d.sh:

#!/bin/sh
sort $1 | uniq > $1_uniq
for line in $(cat $1); do
cat $1_uniq | grep -m1 $line >> $1_out
cat $1_uniq | grep -v $line > $1_uniq2
mv $1_uniq2 $1_uniq
done;
rm $1_uniq

Ejemplo :

./d.sh infile

Podría usar alguna cosa horrible de O (n ^ 2), como esta (Pseudocódigo):

file2 = EMPTY_FILE
for each line in file1:
  if not line in file2:
    file2.append(line)

Esto es potencialmente bastante lento, especialmente si se implementa en el nivel Bash. Pero si sus archivos son razonablemente cortos, probablemente funcionará bien y sería rápido de implementar ( no line in file2 es solo grep -v , y así sucesivamente ).

De lo contrario, por supuesto, podría codificar un programa dedicado, utilizando una estructura de datos más avanzada en la memoria para acelerarlo.

for line in $(sort file1 | uniq ); do
    grep -n -m1 line file >>out
done;

sort -n out

primero haz el ordenamiento,

para cada valor uniqe grep para la primera coincidencia (-m1)

y preservar los números de línea

ordena la salida numéricamente (-n) por número de línea.

puede eliminar los números de línea con sed o awk

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top