Publi

Píldora: Cómo buscar un texto dentro de documentos múltiples ODT de Libreoffice/Openoffice o docx de Microsoft Word

Cuántas veces has recordado haber escrito un documento y no recuerdas dónde lo pusiste. Tienes cientos de archivos de documentos en tu disco duro, o en un servidor y no sabes por dónde empezar a buscar. Con ficheros de texto, podemos utilizar find, grep, egrep, sed y algunos comandos más que, combinados podrán darnos los resultados que buscamos. Aunque los archivos de documentos son algo más complejos internamente.

Ficheros de documentos

Tanto los ficheros de OpenOffice/LibreOffice como los documentos de Microsoft Word Open XML (esos archivos docx que se crean a partir de Microsoft Office 2007. En este post no podremos buscar documentos generados con versiones más antiguas del programa) son en realidad archivos ZIP con muchos archivos XML en su interior en los que se definen contenido, estilos y metadatos. Para los archivos odt, de LibreOffice y OpenOffice, el archivos que contiene los contenidos del documento es content.xml y en Microsoft Word, el archivo está situado en word/document.xml, así que, vamos a intentar, buscar todos los archivos de documentos que haya en una ruta del disco y examinar su contenido para buscar las palabras que necesitamos encontrar. Para ello tendremos que descomprimir el documento y extraer el archivo del documento. Todo de forma automática.

Es cierto que actualmente tenemos programas de búsqueda en escritorio, que examinan periódicamente archivos en varios formatos, procesan dicha información y agilizan la muestra de resultados. Aunque en muchos casos, para acelerar el uso normal del ordenador, muchos los solemos tener desactivados. O, por ejemplo, si tienes los contenidos en un ordenador remoto, una Raspberry PI, o un VPS, puede resultar un poco más complicado hacer dichas búsquedas.

Afortunadamente GNU/Linux nos proporciona herramientas muy buenas para realizar nuestras tareas. Primero ejecutaremos find para obtener todos los archivos de documento a partir de la ruta actual. Aunque podríamos utilizar find con otros parámetros o incluso utilizar locate. Para ello, podemos utilizar estos scripts de una línea, también llamados one-liners.

Documentos de LibreOffice/OpenOffice

Empezaremos con los documentos odt de LibreOffice u OpenOffice. Para ello extraeremos el archivo word/document.xml del archivo de documento y a partir de ahí realizaremos una búsqueda.

find -name ‘*.odt’ | while read file; do unzip -p «$file» «content.xml» | grep -li «TEXTO A BUSCAR» > /dev/null; if [ $? -eq 0 ]; then echo $file; fi; done

De esta forma, find, va pasando archivos odt al resto de la línea. Podríamos hacer fácilmente que no sean todos los archivos, si nos acordamos de parte del nombre podríamos hacer ‘*informe*.odt’ para seleccionar todos los docuentos que contentan la palabra informe y tengan extensión odt; o incluso utilizar -iname en lugar de -name para indicar que busque nombres de archivo en mayúsculas y minúsculas indistintamente. También, con find podríamos seleccionar incluso los archivos por tamaño o por fecha.

En lugar de find -name ‘*.odt’ podríamos utilizar locate ‘*.odt’ para buscar en todo el disco, o en un patrón de directorios determinado. La ventaja de locate es su gran velocidad, aunque primero tendremos que crear una base de datos de archivos del disco (con updatedb) y eso puede tardar un poco.

Una vez tenemos los nombres de archivo que cumplen el patrón, cogemos cada nombre de archivo y ejecutamos unzip -p [archivo] content.xml. La opción -p sirve para extraer el contenido de los archivos directamente a la salida estándar de la aplicación. Si ejecutamos este comando individualmente, veríamos todos los contenidos del fichero en pantalla, vamos, extrae todo a pantalla, en lugar de crear un archivo llamado content.xml. La ventaja de esto es que no necesitamos archivos temporales y todo es mucho más rápido.

La salida de unzip, es decir, el contenido del fichero comprimido, se lo pasamos a grep. En este caso, grep -li «TEXTO» > /dev/null. Con -l, hacemos que grep muestre solo los nombres de archivo donde exista coincidencia, así sólo es necesario que el texto se encuentre una vez en el archivo para que grep finalice la ejecución y devuelva un positivo. Lo malo es que si el texto no está en el archivo tendrá que analizarlo completamente. El argumento -i hace que no importen las mayúsculas y minúsculas, por lo que, aunque en el documento encontremos «CaCaHueTe», podremos decir que grep busque «cacahuete» y lo va a encontrar sin problema. Por último, la salida de grep la redirigimos a /dev/null para que realmente no muestre nada en pantalla. ¿Por qué?

Lo que en realidad analizaremos de grep será el estado de salida del programa. Es decir, internamente, si grep acaba y el archivo que ha analizado contiene el texto que buscamos, devolverá un 0 (normalmente, cuando un programa finaliza bien devuelve un 0 y cuando no, devuelve otra cosa). Entonces, sólo si grep devuelve 0 mostraremos el nombre del archivo en pantalla. Para eso if [ $? -eq 0 ]; then echo $file; fi;.

Documentos de Microsoft Word

Para hacer lo mismo con los documentos de Microsoft Word debemos cambiar el archivo que analizamos. En este caso, analizaremos word/document.xml. Y mantendremos todo el comando igual:

find -name ‘*.docx’ | while read file; do unzip -p «$file» «word/document.xml» | grep -li «TEXTO A BUSCAR» > /dev/null; if [ $? -eq 0 ]; then echo $file; fi; done

Mejorar la búsqueda

Los ficheros que estamos analizando, en realidad son XML, por lo que, junto con el contenido encontramos algunos datos que nos indicarán estilos, objetos empotrados, notas, y demás cosas. Todo esto puede hacer que cuando busquemos algún contenido concreto no lo encontremos. Para mejorar la búsqueda, aunque penalizaremos un poco el tiempo que tardará el script, sobre todo en archivos muy grandes. La clave está en eliminar las etiquetas XML que encontramos en el archivo de contenidos. Un claro ejemplo, podemos verlo si analizamos un fichero HTML. Cuando vemos:

Hola Mundo

En realidad, el código utilizado para el texto es este:

1
<strong>Ho</strong>la Mun<strong>do</strong>

Y si realizamos una búsqueda en texto con grep, por ejemplo, buscando la palabra «Hola». Grep no encontrará nada. Así que, pasaremos el texto por un filtro que eliminará estas etiquetas, con sed. Uno de los usos de este comando es reemplazar cadenas a través de expresiones regulares, pero aunque suene complicado, os la voy a dar preparada. Para ver un ejemplo rápido, vamos a hacer lo siguiente:

echo «Hola Mundo» | grep -i hola

Esto no devolverá nada, porque, como hemos dicho antes, no vamos a encontrar nada en la cadena anterior. Pero,
echo «Hola Mundo» | sed -e ‘s/<[^>]*>//g’ | grep -i hola
Hola Mundo

El segundo ejemplo sí que devuelve el contenido. El objetivo es sustituir globalmente (s/búsqueda/reemplazo/g) cualquier texto que esté entre < y > (<[^>]*< por un texto en blanco.

Creando el script completo

En definitiva, para buscar archivos de LibreOffice / OpenOffice, esos con extensión ODT:

find -name ‘*.odt’ | while read file; do unzip -p «$file» «content.xml» | sed -e ‘s/<[^>]*>//g’ | grep -li «TEXTO A BUSCAR» > /dev/null; if [ $? -eq 0 ]; then echo $file; fi; done

Y para buscar archivos Office Open XML de Microsoft Word, esos con extensión DOCX:

find -name ‘*.docx’ | while read file; do unzip -p «$file» «word/document.xml» | sed -e ‘s/<[^>]*>//g’ | grep -li «TEXTO A BUSCAR» > /dev/null; if [ $? -eq 0 ]; then echo $file; fi; done

Foto principal: unsplash-logoDmitry Ratushny

También podría interesarte....

There are 30 comments left Ir a comentario

  1. nascii /
    Usando Mozilla Firefox Mozilla Firefox 59.0 en Fedora Linux Fedora Linux

    muy interesante, justo ayer por culpa de un libro que ponia el codigo fuente de los ejercicios en .doc me vi en la necesidad de «buscar soluciones» para pasalos directamente a texto sin abrir monstruosos procesadores de texto

    una de las solucienos fue catdoc (de .doc a txt) y otra fue utilizar libreoffice

    libreoffice –headless –convert-to «txt:Text (encoded):UTF8» *.doc

    que puede convertir a otras cosas, directamente desde CLI

    (pd: creo que en los ultimos ejemplos de terminal, el wordpress (supongo) se esta comiendo unos caracteres de la expresion)

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 59.0 en Ubuntu Linux Ubuntu Linux

      Gracias por tu comentario!!
      libreoffice -headless también está muy bien para convertir a texto, incluso soporta el argumento –cat [documento.doc] que te permite mostrar el texto directamente en el terminal, y ya puedes analizarlo sin fichero temporal ni nada. Además, el headless mode tiene muchas opciones, puede quedarse en modo escucha y le puedes «pedir cosas» por socket. 🙂

      Estudiaré lo de los ejemplos del terminal. Ahora mismo lo veo bien, pero puede ser cosa del navegador o de la carga del script… lo mismo hace falta una nueva actualización del plugin 🙂

      Un abrazo!

    2. Wopi /
      Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

      Excelente Nasci. Mira todo lo que puedes encontrar acá https://vendors.mikolo.com/forums/discussion/introductions/entrenimiento-asegurado

  2. Oscar /
    Usando Mozilla Firefox Mozilla Firefox 59.0 en Fedora Linux Fedora Linux

    Hola.
    No entiendo el significado de la expresión regular «]*>» . En principio, lo que busca esto es el caracter «]» repetido 0 o más veces hasta llegar a un «>». ¿Qué sentido tiene esto para encontrar cosas del tipo «». ¿No sería más conveniente, por ejemplo, algo así como «» o más elaborado?
    Gracias

    1. Oscar /
      Usando Mozilla Firefox Mozilla Firefox 59.0 en Fedora Linux Fedora Linux

      Bueno, en el comentario se me han comido los caracteres . Quería decir que si no sería mejor hacer una expresión regular similar a «»

      1. Oscar /
        Usando Mozilla Firefox Mozilla Firefox 59.0 en Fedora Linux Fedora Linux

        Y dale, se me ha comido otra vez. Bueno, desisto

        1. Gaspar Fernández / Post Author
          Usando Mozilla Firefox Mozilla Firefox 59.0 en Ubuntu Linux Ubuntu Linux

          Hola Oscar. La expresión regular de hecho no ha salido bien. Parece que WordPress se ha comido un trozo. Llevaba razón @nascii en el comentario anterior. Voy a arreglarlo ahora.

        2. Gaspar Fernández / Post Author
          Usando Mozilla Firefox Mozilla Firefox 59.0 en Ubuntu Linux Ubuntu Linux

          La expresión es ‘s/<[^>]*>//g el objetivo es que encuentre un < y luego recorra todos los caracteres mientras no sean > y luego encuentre otro > Así puede encerrar la etiqueta XML y nos la podemos cargar a gusto.

          Un saludo!

  3. 토토사이트 /
    Usando Google Chrome Google Chrome 118.0.0.0 en Windows Windows NT

    Excellent works. Continue to write such information on your blog.Your blog left a deep impression on me. I am sure they will benefit from this website.토토사이트

  4. plaster repair /
    Usando Google Chrome Google Chrome 118.0.0.0 en Windows Windows NT

    The program will highlight all instances of that text in the open documents.

  5. 토토사이트 /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Every weekend i used to visit this web page, for the reason that i wish for enjoyment, since this this website conations truly nice funny stuff too.토토사이트

  6. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    The sheer size and selection of these web slots are mind-blowing. Great job. สล็อตเว็บใหญ่

  7. WilliamSEO /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    A commitment of thankfulness is all together for such a remarkable post and the audit, I am completely moved! Keep stuff like this coming. daftar pasar123

  8. WilliamSEO /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    It has completely risen to crown Singapore’s southern shores and without a doubt set her on the worldwide guide of private historic points. Regardless I scored the a bigger number of focuses than I ever have in a season for GS. I figure you would be unable to discover someone with a similar consistency I have had throughout the years so I am content with that. 먹튀검증

  9. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Users should share their experiences with slots breaking easily to raise awareness. เว็บสล็อต

  10. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Incredible data! I as of late went over your blog and have been perusing along. I figured I would leave my first remark. I don’t recognize what to state with the exception of that I have. แหล่งรวมสล็อตทุกค่าย

  11. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I utilize just astounding materials – you can see them at: เว็บสล็อตโรม่า

  12. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Exceptionally fascinating data, worth suggesting. Be that as it may, I suggest this: เกมป๊อกเด้งออนไลน์

  13. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I have a comparable intrigue this is my page read everything deliberately and let me comprehend what you think. 블로그

  14. Angel17 /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Cool. Thanks for sharing this.
    house cleaning services in marietta ga

  15. curved drywall /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    This provides a practical solution for searching text within multiple LibreOffice/OpenOffice ODT documents or Microsoft Word DOCX files.

  16. Mark Wright Fool Me Once Premier Coat /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Thank you for posting such a great article! I found your website perfect for my needs. It contains wonderful and helpful posts. Keep up the good work!. Thank you for this wonderful Article!

  17. ghori92 /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    That you’re allowed to place leaders, however is not one way links, except when they’re just authorised together with regarding niche. транспорт на кола от германия цена

  18. yitzchak kerrigan /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    it is good as well as meanful. it is awesome weblog. Connecting is extremely helpful point. you’ve truly assisted many individuals that go to weblog and supply all of them usefull info. 상품권 매입

  19. jsimitseo /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Good subject, comparative writings are I don’t know whether they are on a par with your work out. concierge doctor

  20. Rank Xone /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    The allure of online casinos is not just about winning money; it’s also about the social aspect. Connecting with players from around the world adds another layer of fun. 프리카지노

  21. WilliamSEO /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    The best article I ran over various years, compose something about it on this page. จำนำรถจอด

  22. Rank Xone /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Raising the stakes at the casino – it’s a thrilling experience every time. 로즈카지노 쿠폰

  23. Rank Xone /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Local SEO services help businesses capitalize on «near me» searches, which have become increasingly popular among mobile users. local seo agency

  24. Rank Xone /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Great info! I recently came across your blog and have been reading along. I thought I would leave my first comment. I don’t know what to say except that I have. รับจำนำรถ

Leave a Reply