¿Cómo mantener el formato de un archivo si usa el comando uniq (en shell)?
-
22-07-2019 - |
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?
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