Pregunta

Tengo un archivo de texto con las palabras, que están separados por una coma, por ejemplo:

word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3

Quiero borrar los duplicados y llegar a ser:

word1, word2, word3, word4, word5, word6, word7

¿Ideas? Creo que, egrep me puede ayudar, pero no estoy seguro, cómo usarlo exactamente ....

¿Fue útil?

Solución

Si se asume que las palabras son una por línea, y el archivo ya está ordenada:

uniq filename

Si el archivo no está ordenada:

sort filename | uniq

Si no están uno por línea, y que no les importa ellos uno por línea:

tr -s [:space:] \\n < filename | sort | uniq

Eso no quita puntuacion, sin embargo, lo que tal vez desee:

tr -s [:space:][:punct:] \\n < filename | sort | uniq

Pero que elimina el guión de palabras con guiones. "Hombre tr" para más opciones.

Otros consejos

ruby -pi.bak -e '$_.split(",").uniq.join(",")' filename?

Voy a admitir los dos tipos de citas son feos.

La creación de una lista única es muy fácil gracias a uniq, aunque la mayoría de los comandos de Unix como una entrada por línea en lugar de una lista separada por comas, por lo que tenemos que empezar mediante la conversión a lo siguiente:

$ sed 's/, /\n/g' filename | sort | uniq
word1
word2
word3
word4
word5
word6
word7

La parte más difícil es poner esto en una línea de nuevo con comas como separadores y no terminadores. He utilizado un perl de una sola línea para hacer esto, pero si alguien tiene algo más idiomática, por favor editar. :)

$ sed 's/, /\n/g' filename | sort | uniq | perl -e '@a = <>; chomp @a; print((join ", ", @a), "\n")'
word1, word2, word3, word4, word5, word6, word7

Aquí hay un script awk que dejará a cada línea en el tacto, solamente la eliminación de las palabras duplicadas:

BEGIN { 
     FS=", " 
} 
{ 
    for (i=1; i <= NF; i++) 
        used[$i] = 1
    for (x in used)
        printf "%s, ",x
    printf "\n"
    split("", used)
} 

que tenía el mismo problema hoy en día .. una lista de palabras con 238.000 palabras, sino alrededor de 40, 000 de los que eran duplicados. Ya los tenía en líneas individuales haciendo

cat filename | tr " " "\n" | sort 

para eliminar los duplicados Yo simplemente hice

cat filename | uniq > newfilename .

Funcionaba perfectamente sin errores y ahora mi archivo está por debajo de 1.45MB 1.01MB a

Me cree que va a sustituir a los espacios con saltos de línea, utilice el uniq para encontrar líneas únicas y vuelva a colocar las nuevas líneas con espacios de nuevo.

supuse que quería las palabras sean únicos en una sola línea, en lugar de todo el archivo. Si este es el caso, entonces el script Perl a continuación va a hacer el truco.

while (<DATA>)
{
    chomp;
    my %seen = ();
    my @words = split(m!,\s*!);
    @words = grep { $seen{$_} ? 0 : ($seen{$_} = 1) } @words;
    print join(", ", @words), "\n";
}

__DATA__
word1, word2, word3, word2, word4, word5, word3, word6, word7, word3

Si desea singularidad durante todo el archivo, sólo puede mover el hash %seen fuera del bucle while (){}.

encontramos con este hilo, mientras trata de resolver tanto el mismo problema. Yo había concatenado varios archivos que contienen las contraseñas, por lo que, naturalmente, había un montón de dobles. Además, muchos caracteres no estándar. Yo realmente no tienen por qué ellos ordenados, pero parecía que iba a ser necesario para uniq.

He intentado:

sort /Users/me/Documents/file.txt | uniq -u
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `t\203tonnement' and `t\203tonner'

Probado:

sort -u /Users/me/Documents/file.txt >> /Users/me/Documents/file2.txt
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `t\203tonnement' and `t\203tonner'.

e incluso trató de pasarla a través de gato en primer lugar, sólo para poder ver si nos iban a dar una entrada adecuada.

cat /Users/me/Documents/file.txt | sort | uniq -u > /Users/me/Documents/file2.txt
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `zon\351s' and `zoologie'.

No estoy seguro de lo que está pasando. La cuerdas "t \ 203tonnement" y "t \ 203tonner" no se encuentran en el archivo, aunque "t / 203" y "tonnement" se encuentran, pero en líneas separadas, no contiguas. Lo mismo con "zon \ 351s".

Lo que finalmente funcionó para mí fue:

awk '!x[$0]++' /Users/me/Documents/file.txt > /Users/me/Documents/file2.txt

También conserva palabras cuya única diferencia era el caso, que es lo que quería. No necesitaba la lista ordenada, así que estaba bien que no lo era.

Y no se olvide de la opción -c para la utilidad uniq si usted está interesado en obtener un recuento de las palabras también.

abrir archivo con vim (vim filename) y ejecute tipo comando con la bandera única (:sort u).

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