User Tag List

Resultados 1 al 12 de 12

Tema: Herramienta para formatear ficheros de texto plano

  1. #1

    Fecha de ingreso
    Jun 2003
    Ubicación
    Madrid
    Mensajes
    516
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    16
    Agradecer Thanks Received 
    94
    Thanked in
    Agradecido 44 veces en [ARG:2 UNDEFINED] posts

    Herramienta para formatear ficheros de texto plano

    Hola a todos.
    Quiero formatear una serie de textos en ficheros de texto plano, algunos más largos que otros, para que cada línea termine con un punto. Si, además, se consigue que la línea tenga una longitud mínima (aunque hubiera 2 frases terminadas con punto en la misma línea) sería ya perfecto.
    Por ejemplo, dado este texto:

    Código:
    Y las formas angélicas convertíanse en insignificantes espectros con cabeza de luego,
    y claramente comprendí que no debía esperar auxilio alguno. Entonces, como una
    magnífica nota musical, se insinuó en mi imaginación la idea del inefable reposo que
    nos espera en la tumba. Llegó suave, furtivamente. Sospecho que necesité un gran
    rato para apreciarla por completo. Pero en el preciso instante en que mi espíritu
    comenzaba a sentir claramente esa idea, y a acariciarla, las figuras de los jueces se
    desvanecieron como por arte de magia. Los hachones se redujeron a la nada. Sus
    luces se apagaron por completo, y sobrevino la negrura de las tinieblas. Todas las
    sensaciones fingieron desaparecer como en una zambullida loca y precipitada del
    alma en el Hades. Y el Universo fue sólo noche, silencio, quietud.
    Estaba desvanecido. Pero, sin embargo, no puedo decir que hubiese perdido la
    conciencia del todo. La que me quedaba, no intentaré definirlo. Ni describirlo
    siquiera. Pero, en fin, todo no estaba perdido. En medio del más profundo sueño…,
    ¡no! En medio del delirio…, ¡no! En medio del desvanecimiento…, ¡no! En medio de
    la muerte…, ¡no! Si fuera de otro modo, no habría salvación para el hombre. Cuando
    nos despertamos del más profundo sueño, rompemos la telaraña de algún sueño. Y,
    no obstante, un segundo más tarde es tan delicado este tejido, que no recordamos
    haber soñado.
    querría convertirlo en algo como:

    Código:
    Y las formas angélicas convertíanse en insignificantes espectros con cabeza de luego, y claramente comprendí que no debía esperar auxilio alguno. 
    Entonces, como una magnífica nota musical, se insinuó en mi imaginación la idea del inefable reposo que nos espera en la tumba. 
    Llegó suave, furtivamente. Sospecho que necesité un gran rato para apreciarla por completo. 
    Pero en el preciso instante en que mi espíritu comenzaba a sentir claramente esa idea, y a acariciarla, las figuras de los jueces se desvanecieron como por arte de magia. 
    Los hachones se redujeron a la nada. Sus luces se apagaron por completo, y sobrevino la negrura de las tinieblas. 
    Todas las sensaciones fingieron desaparecer como en una zambullida loca y precipitada del alma en el Hades. 
    Y el Universo fue sólo noche, silencio, quietud. Estaba desvanecido. Pero, sin embargo, no puedo decir que hubiese perdido la conciencia del todo. 
    La que me quedaba, no intentaré definirlo. Ni describirlo siquiera. Pero, en fin, todo no estaba perdido. 
    En medio del más profundo sueño…, ¡no! En medio del delirio…, ¡no! En medio del desvanecimiento…, ¡no! 
    En medio de la muerte…, ¡no! Si fuera de otro modo, no habría salvación para el hombre. 
    Cuando nos despertamos del más profundo sueño, rompemos la telaraña de algún sueño. Y, no obstante, un segundo más tarde es tan delicado este tejido, que no recordamos haber soñado.
    ¿Se os ocurre algún maquinillo que lo haga de una forma más o menos automática? Si no, trataré de hacerme un script que lo apañe...

    Muchas gracias!
    El pasado ha pasado y por él nada hay que hacer... el presente es un fracaso y el futuro no se ve... (Cerebros destruidos/Eskorbuto)

  2. #2

    Fecha de ingreso
    Sep 2006
    Mensajes
    4,750
    Mencionado
    23 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    637
    Agradecer Thanks Received 
    569
    Thanked in
    Agradecido 423 veces en [ARG:2 UNDEFINED] posts
    A mi solo se me ocurre con un script/programa.
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.

  3. #3

    Fecha de ingreso
    Jun 2003
    Ubicación
    Madrid
    Mensajes
    516
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    16
    Agradecer Thanks Received 
    94
    Thanked in
    Agradecido 44 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por swapd0 Ver mensaje
    A mi solo se me ocurre con un script/programa.
    Sí, algo que exista ya es un poco rebuscado pero había que intentarlo... luego trataré de hacer algo, a ver qué saco =)
    El pasado ha pasado y por él nada hay que hacer... el presente es un fracaso y el futuro no se ve... (Cerebros destruidos/Eskorbuto)

  4. #4

    Fecha de ingreso
    Jan 2012
    Mensajes
    482
    Mencionado
    5 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    48
    Agradecer Thanks Received 
    166
    Thanked in
    Agradecido 99 veces en [ARG:2 UNDEFINED] posts
    Por si usas Linux o similar, fold y fmt sirven para reformatear un texto cambiando la anchura de las líneas, pero no hay ninguna utilidad que sirva para hacer lo que planteas. Con AWK (lenguaje de script clásico para procesar textos) lo de formatear por oraciones es lo suficientemente simple como para resolverlo en una línea:

    Código:
    awk 'BEGIN {RS="[.]( *|\n)"} {gsub(" *\n *"," "); print $0 "."}' texto.txt > texto_formateado.txt
    Añadiendo el requisito de que las líneas tengan una longitud mínima la cosa se complica. El script que se me ocurre sería:

    Código:
    BEGIN {
        line_len = 80   # longitud minima
        RS="[.]( *|\n)"
    }
    {
        gsub(" *\n *"," ")
        if (line == "")
            line = $0 "."
        else
            line = line " " $0 "."
        if (length(line) >= line_len) {
            print line
            line = ""
        }
    }
    END {
        if (line != "")
        print line
    }
    A ejecutar:

    Código:
    awk -f script.awk texto.txt > texto_formateado.txt
    Última edición por Trenz; 21/08/2019 a las 20:56

  5. #5

    Fecha de ingreso
    Jun 2004
    Ubicación
    en babia
    Mensajes
    2,325
    Mencionado
    27 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    152
    Agradecer Thanks Received 
    281
    Thanked in
    Agradecido 154 veces en [ARG:2 UNDEFINED] posts
    Notepad++ es tu amigo.

    tiene una potente herramienta de sustitucion que quizas te sirva.

    slaudos

  6. #6

    Fecha de ingreso
    Jun 2003
    Ubicación
    Madrid
    Mensajes
    516
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    16
    Agradecer Thanks Received 
    94
    Thanked in
    Agradecido 44 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por Trenz Ver mensaje
    Por si usas Linux o similar, fold y fmt sirven para reformatear un texto cambiando la anchura de las líneas, pero no hay ninguna utilidad que sirva para hacer lo que planteas. Con AWK (lenguaje de script clásico para procesar textos) lo de formatear por oraciones es lo suficientemente simple como para resolverlo en una línea:

    Código:
    awk 'BEGIN {RS="[.]( *|\n)"} {gsub(" *\n *"," "); print $0 "."}' texto.txt > texto_formateado.txt
    Añadiendo el requisito de que las líneas tengan una longitud mínima la cosa se complica. El script que se me ocurre sería:

    Código:
    BEGIN {
        line_len = 80   # longitud minima
        RS="[.]( *|\n)"
    }
    {
        gsub(" *\n *"," ")
        if (line == "")
            line = $0 "."
        else
            line = line " " $0 "."
        if (length(line) >= line_len) {
            print line
            line = ""
        }
    }
    END {
        if (line != "")
        print line
    }
    A ejecutar:

    Código:
    awk -f script.awk texto.txt > texto_formateado.txt
    Muchas gracias, Trenz, luego en el trabajo lo pruebo que ahí tengo un linux... tengo la espinita clavada de aprender awd, sed y todas esas cosas pero me come el día a día y nunca saco tiempo.

    -----Actualizado-----

    Cita Iniciado por tognin Ver mensaje
    Notepad++ es tu amigo.

    tiene una potente herramienta de sustitucion que quizas te sirva.

    slaudos
    Gracias Tognin, lo intenté usando macros de Notepad++ pero no lo logré. Si no lo consigo con los scripts de Trenz, intentaré de nuevo con la sustitución de Notepad++.
    El pasado ha pasado y por él nada hay que hacer... el presente es un fracaso y el futuro no se ve... (Cerebros destruidos/Eskorbuto)

  7. #7

    Fecha de ingreso
    Jan 2012
    Mensajes
    482
    Mencionado
    5 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    48
    Agradecer Thanks Received 
    166
    Thanked in
    Agradecido 99 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por OscarBraindeaD Ver mensaje
    Muchas gracias, Trenz, luego en el trabajo lo pruebo que ahí tengo un linux... tengo la espinita clavada de aprender awd, sed y todas esas cosas pero me come el día a día y nunca saco tiempo.
    Hmmm, si los ficheros de texto proceden de Windows los finales de línea van a ser '\r\n' (los caracteres ASCII retorno de carro y nueva línea) en lugar de sólo '\n'. No conté con eso. Una forma de solucionarlo al vuelo sin tocar el script es quitar el '\r' antes de formatear y añadirlo después:

    Código:
    sed 's/\r$//' texto.txt | awk -f script.awk | sed 's/$/\r/' > texto_formateado.txt

  8. #8

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    9,205
    Mencionado
    63 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    119
    Agradecer Thanks Received 
    806
    Thanked in
    Agradecido 413 veces en [ARG:2 UNDEFINED] posts
    Otra opción: https://vi.stackexchange.com/questio...tence-per-line

    Siguiendo esa misma idea, podrías probar:

    Código:
    sed ':a;{N;s/\n/ /;ba}' texto.txt | sed 's/\([\.!?]\)/\1\n/g' | sed 's/^\s*//'
    Código:
    Y las formas angélicas convertíanse en insignificantes espectros con cabeza de luego, y claramente comprendí que no debía esperar auxilio alguno.
    Entonces, como una magnífica nota musical, se insinuó en mi imaginación la idea del inefable reposo que nos espera en la tumba.
    Llegó suave, furtivamente.
    Sospecho que necesité un gran rato para apreciarla por completo.
    Pero en el preciso instante en que mi espíritu comenzaba a sentir claramente esa idea, y a acariciarla, las figuras de los jueces se desvanecieron como por arte de magia.
    Los hachones se redujeron a la nada.
    Sus luces se apagaron por completo, y sobrevino la negrura de las tinieblas.
    Todas las sensaciones fingieron desaparecer como en una zambullida loca y precipitada del alma en el Hades.
    Y el Universo fue sólo noche, silencio, quietud.
    Estaba desvanecido.
    Pero, sin embargo, no puedo decir que hubiese perdido la conciencia del todo.
    La que me quedaba, no intentaré definirlo.
    Ni describirlo siquiera.
    Pero, en fin, todo no estaba perdido.
    En medio del más profundo sueño…, ¡no!
    En medio del delirio…, ¡no!
    En medio del desvanecimiento…, ¡no!
    En medio de la muerte…, ¡no!
    Si fuera de otro modo, no habría salvación para el hombre.
    Cuando nos despertamos del más profundo sueño, rompemos la telaraña de algún sueño.
    Y, no obstante, un segundo más tarde es tan delicado este tejido, que no recordamos haber soñado.
    Última edición por juanvvc; 22/08/2019 a las 18:14
    "Todo es absolutamente falso, salvo alguna cosa"

  9. #9

    Fecha de ingreso
    Jan 2012
    Mensajes
    482
    Mencionado
    5 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    48
    Agradecer Thanks Received 
    166
    Thanked in
    Agradecido 99 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por juanvvc Ver mensaje
    Siguiendo esa misma idea, podrías probar:

    Código:
    sed ':a;{N;s/\n/ /;ba}' texto.txt | sed 's/\([\.!?]\)/\1\n/g' | sed 's/^\s*//'
    Está claro que me obcequé con el punto XD. La solución que planteaba en AWK no sirve si se quieren tener en cuenta los signos de cierre de interrogación y exclamación. Así que es mejor lo que propones. Y no dejan de ser soluciones toscas, que siempre se pueden mejorar, claro. Pero para hacerlo realmente bien habría que usar una librería de procesado de lenguaje natural.
    Última edición por Trenz; 23/08/2019 a las 16:55

  10. #10

    Fecha de ingreso
    Jun 2003
    Ubicación
    Madrid
    Mensajes
    516
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    16
    Agradecer Thanks Received 
    94
    Thanked in
    Agradecido 44 veces en [ARG:2 UNDEFINED] posts
    Hola a todos, probé los scripts que puso Trenz al inicio y funcionan realmente bien. Pero al pasarlo a windows, se descabalaba todo con los saltos de línea. Acabo de leer vuestros comentarios avisando precisamente de eso
    Al final lo que hice fue una macro de editplus que, primero ponía todo el texto en una única línea y, volviendo al inicio del texto, otra macro que buscase puntos y saltase de línea al encontrarlo. Luego ha habido bastante trabajo manual para exclamaciones, puntos suspensivos, etc.
    Perdonad que no comentase que era para windows y muchas gracias por vuestros scripts, ideas y soluciones. Me los guardo porque nos necesitaré en breve otra vez y lo que proponéis me ahorrará mucho curro. Los textos de esta remesa eran las "narraciones extraordinarias" de Edgar Allan Poe. He hecho una pequeña aplicación en android que los lee y los narra (con la voz del GPS). Eran textos más o menos cortos y no ha sido excesivamente doloroso. Quiero hacer lo mismo con alguna novela de Poe (aventuras de Arthur Gordon Pym) y relatos y novelas de Lovecraft, que de media tienen más longitud y hacerlo con la macro puede ser doloroso, así que probaré las correcciones que proponéis a los scripts originales.
    Muchas gracias de nuevo a todos!
    El pasado ha pasado y por él nada hay que hacer... el presente es un fracaso y el futuro no se ve... (Cerebros destruidos/Eskorbuto)

  11. #11

    Fecha de ingreso
    Jan 2012
    Mensajes
    482
    Mencionado
    5 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    48
    Agradecer Thanks Received 
    166
    Thanked in
    Agradecido 99 veces en [ARG:2 UNDEFINED] posts
    Lo que hiciste al final es similar a lo que propone Juanvvc: con la primera invocación de sed junta todo el texto en una única línea y con la segunda introduce saltos de línea después de cada punto, cierre de interrogación o cierre de exclamación. De todas formas, ninguno de esos signos de puntuación finalizan siempre una oración, como sucede con el punto en el caso de las abreviaturas. Se puede afinar más la expresión regular para tener en cuenta si lo que sigue parece el inicio de otra oración: una letra mayúscula precedida opcionalmente por '¿' o '¡'. Es decir, sería: sed -E 's/([.?!])\s+([¿¡]?[A-Z])/\1\n\2/g'. Probablemente funcione en la mayoría de los casos, pero seguirá fallando en algunos. En realidad es un problema que pertenece al ámbito del procesado de lenguaje natural. Echando un vistazo rápido, parece que una de las librerías de ese tipo más populares es NLTK para Python. No creo que sea difícil montar una solución por esa vía.

  12. #12

    Fecha de ingreso
    Jan 2012
    Mensajes
    482
    Mencionado
    5 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    48
    Agradecer Thanks Received 
    166
    Thanked in
    Agradecido 99 veces en [ARG:2 UNDEFINED] posts
    Por si te vuelves a poner con el tema... Acabo de estar viendo algunos ejemplos de uso de NLTK y haciendo algunas pruebas, ya que me picó la curiosidad. Te dejo el script en Python. Tendrías que instalar la librería NLTK y el segmentador punkt (yo simplemente cojo el fichero PY3/spanish.pickle y lo cargo desde el directorio de trabajo).

    Código:
    import sys
    import nltk.data
    
    LONG_MIN = 0   # longitud minima de las lineas de salida
    
    with open(sys.argv[1], 'r') as file:
        texto = file.read().replace('\n', ' ')
    
    tokenizer = nltk.data.load('./spanish.pickle')
    oraciones = tokenizer.tokenize(texto)
    
    linea = ''
    for oracion in oraciones:    
        linea += (' ' if linea else '') + oracion
        if len(linea) >= LONG_MIN:
            print('{}'.format(linea))
            linea = ''
    if linea:
        print('{}'.format(linea))
    Con este texto de ejemplo

    Código:
    Tome Ud. Alejando lo cogió. Tome, Sr. García. 1724 fue el año en que sucedió. Tú
    dijiste que habías visto a... ¿a quién?, que no lo recuerdo. Ana, María... Yo
    qué sé cómo se llamaba. ¿Tanto te interesa? ¡Qué alegre estaba!, ¡cómo se
    puso!, ¡qué brincos dio! ¡Fue una gran noticia!
    Con la expresión regular que comentaba antes se obtiene:

    Código:
    Tome Ud.
    Alejando lo cogió.
    Tome, Sr.
    García. 1724 fue el año en que sucedió.
    Tú dijiste que habías visto a... ¿a quién?, que no lo recuerdo.
    Ana, María...
    Yo qué sé cómo se llamaba.
    ¿Tanto te interesa?
    ¡Qué alegre estaba!, ¡cómo se puso!, ¡qué brincos dio!
    ¡Fue una gran noticia!
    Como era de esperar, falla en "Sr. García" y "García. 1724". El script que usa NLTK lo hace bien:

    Código:
    Tome Ud.
    Alejando lo cogió.
    Tome, Sr. García.
    1724 fue el año en que sucedió.
    Tú dijiste que habías visto a... ¿a quién?, que no lo recuerdo.
    Ana, María...
    Yo qué sé cómo se llamaba.
    ¿Tanto te interesa?
    ¡Qué alegre estaba!, ¡cómo se puso!, ¡qué brincos dio!
    ¡Fue una gran noticia!

  13. El siguiente usuario agradece a Trenz este mensaje:

    hardyx (27/08/2019)

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •