8

I have a folder with subfolders in it and many libreoffice documents (.odt).

I need to find in which one there's a particular phrase.

I tried grep -ir "search phrase here" . but it only found the search phrase in an xml file.

Is there a way to search in documents that are not plain text files?

4
  • 1
    Have a look at Recoll. Jun 22, 2013 at 4:30
  • Is there a command line alternative?
    – To Do
    Jun 22, 2013 at 10:09
  • Recoll does have a poweful CLI interface. Jun 23, 2013 at 1:15
  • 1
    @Glutanimate, here's a thread specific to .odt files: ubuntuforums.org/showthread.php?t=899179. Recoll wants to pull in lot of qt dependencies.
    – user25656
    Jan 22, 2014 at 6:48

2 Answers 2

6

Finally, I resolved to using Recoll. It does a good job at finding information in files. Indexing is however slow and takes a lot of resources. This is not a problem if you do not run Recoll as a daemon, but only update the index manually when you're not using the computer.

To install it:

sudo apt install recoll

Screenshot

3
  • 1
    The "refresh index" option seems to be smart - building index on some 1250 files took a few dozen seconds, but after adding only 1 new file the refresh was instantaneous. It helps to just index your ~/Documents (or wherever you keep what you want to search), instead of the home directory (hidden configs?), or even the whole filesystem etc. Jul 16, 2017 at 21:08
  • There is also a command line interface with the commands recollq , recollindex and xadump .
    – Flimm
    Nov 8, 2023 at 9:32
  • If you would like to add support for more file types, like PDF, and rar archives, then install the suggested dependencies by running sudo apt install --install-recommends --install-suggested recoll (when installing recoll)
    – Flimm
    Nov 8, 2023 at 9:39
2

I have the similar problem with OpenDocument (ODT document, OTT template) and Microsoft Word (DOC and DOCX documents, DOT and DOTX templates) files.

Currently, I'm happy with the following Bash script for recursive search:

#!/bin/sh
if [ "$#" -ne 1 ]; then
    echo $"Usage: $(basename "$0") search_pattern"
    echo "You should have installed the following packages: odt2txt, docx2txt and libreoffice-writer"
    exit 1
fi

search_pattern="$1"
printf "Looking for: $search_pattern\n"

find . -name '*.odt' -o -name '*.ott' -o \
  -name '*.docx' -o -name '*.dotx' -o \
     -name '*.doc' -o -name '*.dot' \
     -type f | while read -r doc; do

    doc_fullfilename=$(basename -- "$doc")
    doc_filename="${doc_fullfilename%.*}"
    doc_filetype="${doc_fullfilename##*.}"

    case $doc_filetype in
        'odt' | 'ott')
        (odt2txt "$doc" 2>/dev/null | grep -i "$search_pattern") && echo "^ found in ODT/OTT: $doc" && echo
        ;;
        'docx' | 'dotx')
        (docx2txt "$doc" - 2>/dev/null | grep -i "$search_pattern") && echo "^ found in DOCX/DOTX: $doc" && echo
        ;;
        'doc'| 'dot')
        out_dir=/tmp
        lowriter --headless --convert-to txt:Text "$doc" --outdir "$out_dir" 2>&1 > /dev/null
        grep -i "$search_pattern" "$out_dir/$doc_filename.txt" && echo "^ found in DOC/DOT: $doc" && echo
        ;;
    esac
: ; done

It shows search results and file-names.

Notes:

  1. the script uses three external programs - odt2txt (for ODT/OTT), docx2txt (for DOCX/DOTX), libreoffice-writer (for DOC/DOT).
  2. theoretically, all these programs may be changed to only one - LibreOffice Writer, but it significantly slower for ODT/OTT and DOCX/DOTX.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .