Estoy haciendo un rápido análisis para ingenuo booleano para sustraer información del sistema, y me gustaría usar awk, grep, egrep, sed o cosa similar y tuberías para dividir un archivo de texto en palabras y guardarlas en otro archivo con una palabra por línea. Ejemplo de mi archivo cotains:

Hola mundo, hablo español y no sé si escribí bien la
pregunta, ojalá me puedan entender y ayudar
Adiós.

El archivo de salida debe contiene:

Hola
mundo
hablo
español
...

Gracias!

  • Son estos una palabra o 2: O'Hara, X-ray, over-priced, dog's, 27, $27, $27.00, 27lbs?
  • Entonces, ¿qué distingue a la «palabra»de «palabra-separadores»?
  • He publicado una «respuesta» a lo que pienso que usted necesita y que ninguno de los publicados soluciones le dará. Pensar acerca de esto y nos deja saber…
  • cat file | sed "s/ /\n/g"
InformationsquelleAutor jaundavid | 2013-03-19

11 Comentarios

  1. 47

    Usando tr:

    tr -s '[[:punct:][:space:]]' '\n' < file
    • Sencillo y limpio. Solución agradable.
    • +1 creo que esta es probablemente la más cercana a lo que el cartel quiere, pero él dijo que O'Hara y X-ray y algunas otras combinaciones que incluyen [:punct:] caracteres debe ser considerado como una palabra que esta solución no haría. Había probablemente también desea que la salida de corriente a «ordenar», así que se pone cada palabra una vez en la salida, pero ahora estoy adivinando.
    • Tal vez ampliar [:punct:] y quitar - y ', realizando: tr -s '[*!"#\$%&\(\)\+,\\\.\/:;<=>\[email protected]\[\\\\]^_`\{|\}~][:space:]]' '\n' < file; opcionalmente como Ed Morton también sugiere ordenar y tal vez agregar frecuencia: tr -s '[*!"#\$%&\(\)\+,\\\.\/:;<=>\[email protected]\[\\\\]^_`\{|\}~][:space:]]' '\n' < file | sort | uniq -c | sort -nr. Un poco enredado pero tal vez buena. Piense también en caso carácter. Adecuado encadenamiento puede ser complicado 🙂
  2. 3

    Utilizando sed:

    $ sed -e 's/[[:punct:]]*//g;s/[[:space:]]\+/\n/g' < inputfile

    básicamente esto elimina todos los signos de puntuación y sustituye a todos los espacios con saltos de línea. Esto supone que su sabor de sed entiende \n. Algunos no-en cuyo caso sólo se puede utilizar un literal de cadena de caracteres de nueva línea en su lugar (es decir, mediante su inclusión dentro de su cita).

    • +1 para el manejo de los signos de puntuación
  3. 2

    grep -o imprime sólo las partes de la coincidencia de la línea que coincide con el patrón

    grep -o '[[:alpha:]]*' file
    • Puede usted explicar más en mí, por favor? Yo’dont entender el patrón, gracias.
    • Es un estándar llamado a clases para los símbolos que grep puede utilizar. Este, [:alpha:], por ejemplo, significa «todos los caracteres del alfabeto». Como [A-Za-z], salvo que es consciente de la configuración regional actual. También, es [:alpha:], no :alpha: – soportes son una parte del nombre de la clase.
    • * significa zero or more repetitions. Probablemente no desea incluir palabras con caracteres cero :-). Una BRE de 1 o más sería [[:alpha:]][[:alpha:]]* mientras que un ERE sería [[:alpha:]]+
    • Esto sólo coincide con la primera palabra en cada línea en el archivo de entrada. No es una solución. También, mientras que la ‘palabra’ no está definido, tal vez sería una buena cosa para suponer que una palabra puede contener otros caracteres que en el alfabeto, tales como los dígitos, los apóstrofes…?
    • grep con -o opción solo omite vacío partidos por lo que es completamente legal. Aún así, en otras utilidades/idiomas que podría ser significativa, gracias por la corrección.
  4. 1
    cat input.txt | tr -d ",." | tr " \t" "\n" | grep -e "^$" -v

    tr -d «,.» borra «,» y «.»

    tr «\t» «\n» cambios de espacios y tabulaciones a saltos de línea

    grep -e «^$» -v elimina las líneas en blanco (en caso de que dos o más espacios)

    • Estoy usando ubuntu, hay tr en ubuntu?, qué paquete debo instalar?
    • Estoy usando debian estable y cat, tr y grep hay por defecto, es el mismo con ubuntu en mi humilde opinión. tr es parte de la «coreutils» paquete en debian y ubuntu.
    • Has elegido una solución que se considere «stop!» y «stop?» como 2 diferentes «palabras». Dudo si eso es lo que quiere y hay MUCHOS otros problemas con esta solución. Si puedes nos acaba de decir en palabras lo que distingue a la «palabra»de «palabra-separadores» en su mente, entonces podemos dar probablemente una solución.
  5. 1

    este awk línea puede trabajar demasiado?

    awk 'BEGIN{FS="[[:punct:] ]*";OFS="\n"}{$1=$1}1'  inputfile
    • ¿Cuál es la media de {$1=$1}1? La imaginación gracias!
    • Es la fuerza de awk interno para el uso de la OFS variable sin el uso de las comas para separar los campos a mostrar
  6. 1

    Con base en sus respuestas hasta el momento, CREO que lo que probablemente usted está buscando es tratar las palabras como secuencias de caracteres separados por espacios, comas, de condena de los caracteres de final (es decir,».» «!» o «?» en inglés) y otros personajes que normalmente NO se encuentran en combinación con caracteres alfanuméricos (por ejemplo, «<» y «, » pero no ' - # $ %). Ahora, «.» es una sentencia de carácter final, pero usted dijo que $27.00 debe ser considerada como una «palabra» para . necesita ser tratada de forma diferente dependiendo del contexto. Creo que el mismo es probablemente cierto «-» y tal vez algunos otros personajes.

    Por lo que necesita una solución que se va a convertir esto:

    I have $27.00. We're 20% under-budget, right? This is #2 - mail me at "[email protected]".

    a esto:

    I
    have
    $27.00
    We're
    20%
    under-budget
    right
    This
    is
    #2
    mail
    me
    at 
    [email protected]

    ¿Es correcto?

    Probar esta usando GNU awk para que podamos set RS a más de un personaje:

    $ cat file
    I have $27.00. We're 20% under-budget, right? This is #2 - mail me at "[email protected]".
    
    $ gawk -v RS="[[:space:]?!]+" '{gsub(/^[^[:alnum:]$#]+|[^[:alnum:]%]+$/,"")} $0!=""' file
    I
    have
    $27.00
    We're
    20%
    under-budget
    right
    This
    is
    #2
    mail
    me
    at
    [email protected].com

    Tratar de llegar con algunos otros casos de prueba para ver si esto siempre hace lo que quiere.

    • Sí Ed Morton, yo no había pensado en esto casos, es importante para mí resolver este problema ahora y no tengo ideas de reglas que podrían trabajar.
    • He actualizado mi respuesta, vea lo que usted piensa.
    • Heh. Cubierto una gran cantidad de casos que hay. Pero probablemente hay un trillón de más… por no hablar de las diferencias entre los idiomas. Pero una buena solución exige una buena comprensión de los requisitos. Pregunta debe ser más detallada que alguien le dé una buena solución. En esta etapa yo recomiendo echar un vistazo a lo que las bibliotecas están disponibles para el lenguaje natural de análisis. Tal vez hay una buena tokenizer por ahí que ya cubre muchos de los problemas comunes. Eche un vistazo a Ruby, Python, Perl tal vez.
    • de acuerdo. usted no puede hacer este trabajo de manera robusta con una rápida secuencia de comandos como mucho en lenguaje natural depende del contexto de lo mejor de la OP puede esperar es una solución que es «lo suficientemente bueno» para sus necesidades.
  7. 0

    Una muy simple opción podría ser primero,

    sed 's,\(\w*\),\n,g' file

    cuidado doens no manejar ni apóstrofes ni signos de puntuación

  8. 0

    Utilizando perl:

    perl -ne 'print join("\n", split)' < file

    • No ponctuation manipulación :/
    • Nada de especial tratamiento de la puntuación fue solicitado. Una definición de ‘palabra’ es algo separados por un carácter de espacio. Diferentes idiomas tienen diferentes signos de puntuación. A veces puntuación es información importante para retener al encadenamiento. Por lo tanto, implementación simple que es fácil de extender, si es necesario.
  9. 0

    Con :

    perl -pe 's/(?:\p{Punct}|\s+)+/\n/g' file

    Salida

    Hola
    mundo
    hablo
    español
    y
    no
    sé
    si
    escribí
    bien
    la
    pregunta
    ojal
    me
    puedan
    entender
    y
    ayudar
    Adiós
  10. 0

    perl -ne ‘imprimir join(«\n», split)’

    Lo siento @jsageryd

    Que uno forro no da la respuesta correcta, ya que se une la última palabra en la línea con la primera palabra en siguiente.

    Esto es mejor, pero genera una línea en blanco para cada línea en blanco en el src. La tubería a través de | sed ‘/^$/d’ para fijar que

    perl -ne ‘{ print join(«\n»,split(/[[:^palabra:]]+/)),»\n»; }’

Dejar respuesta

Please enter your comment!
Please enter your name here