3

I am looking for:

  1. a way to search inside odt files (i.e. search for contents, not name)
  2. that does not require any kind of indexing
  3. that is graphical and very user-friendly (for a relatively old person, who does not like computers much)

I know that it is possible to have 1) and 2):

for x in `find . -iname '*odt'`; do odt2txt $x | grep Query; done

works well enough, and it's pretty fast. But I wonder if there is already a good solution that does this with a GUI (or can be adapted to do this easily)

Glutanimate
  • 21,393
josinalvo
  • 6,947
  • 5
  • 37
  • 51
  • 1
    First your script have problems if there are spaces in the filename. To solve this look at this https://unix.stackexchange.com/questions/9496/looping-through-files-with-spaces-in-the-names – TuKsn Jun 10 '14 at 17:26
  • 1
    How about a nautilus script with zenity input for the search term? – TuKsn Jun 10 '14 at 18:02
  • Yeah zenity can output the results as well. – hytromo Jun 10 '14 at 19:49

1 Answers1

4

Solution using a yad script


Overview

Unfortunately there's no existing GUI option that would be able to search through LibreOffice documents without creating an index first (e.g. Recoll, Tracker). The closest one I found was gnome-search-tool but it only supports plain text files.

Because I was looking for the same type of functionality a few months ago I decided to sit down and see what I could come up with myself. So, without further ado, here's the script I wrote:

ODT finder

#!/bin/bash

NAME: ODT finder

AUTHOR: (c) 2014 Glutanimate (https://github.com/Glutanimate)

LICENSE: GNU GPLv3 (http://www.gnu.de/documents/gpl-3.0.en.html)

DEPENDENCIES yad libreoffice unoconv

Dialogs

Title="ODT finder" TxtEntry="Please enter the <b>directory</b> you would like to search through
and the <b>search term.</b>" ErrNoArgs="ERROR: Please make sure to supply both a search path and search term" ErrNoReslt="No results found."

Variables

declare -A Results

Functions

dialog_options(){ SearchOptions="$(yad --form --title="$Title" --text="$TxtEntry"
--width=400 --height=200 --center
--field="Directory":DIR
--field="Search term" )"

RET=&quot;$?&quot;

if [[ &quot;$RET&quot; != &quot;0&quot; ]]; then
  echo &quot;Aborting&quot;
  exit 1
fi   

SearchPath=&quot;$(echo &quot;$SearchOptions&quot; | cut -d '|' -f1)&quot;
SearchTerm=&quot;$(echo &quot;$SearchOptions&quot; | cut -d '|' -f2)&quot;

echo &quot;Path: $SearchPath&quot;
echo &quot;Query: $SearchTerm&quot;

if [[ -z &quot;$SearchPath&quot; || -z &quot;$SearchTerm&quot; ]]; then
  dialog_error &quot;$ErrNoArgs&quot;
  dialog_options
fi

}

odt_search(){ while IFS= read -r -d '' File; do Match="$(unoconv --format txt --stdout "$File" 2> /dev/null | grep -m "1" -i "$SearchTerm")" if [[ -n "$Match" ]] then echo "Match found for $File:" echo "$Match" Results["$File"]="$Match" else echo "No Result found in $File" fi done < <(find "$SearchPath" -type f -name '*.odt' -print0) echo "1" > "$SearchState" }

dialog_error(){ yad --title="$Title"
--center --width="400" --height="100"
--image=dialog-error
--window-icon=dialog-error
--class="$WMCLASS"
--text="$1"
--button="OK":0 2> /dev/null }

dialog_progress(){ sleep 0.5 while true; do if [[ "$(cat "$SearchState")" = "1" ]]; then break else echo "#Searching..." sleep 0.5 fi done |
yad --progress --pulsate --auto-close
--width=350 --height=100
--title="$Title"
--text="Searching for '<b>$SearchTerm</b>' in '<b>$SearchPath</b>' ..."
--button='_Cancel!gtk-cancel!':1
2> /dev/null PROG_RET="$?" if [[ "$PROG_RET" != "0" ]] then kill -s TERM "$TOP_PID" fi }

dialog_results(){ TxtMain="Search results for '<b>$SearchTerm</b>' in '<b>$SearchPath</b>'"

if [[ -z &quot;${Results[@]}&quot; ]]; then
  dialog_error &quot;$ErrNoReslt&quot;
  exit 1
fi

for File in &quot;${!Results[@]}&quot;; do
  echo &quot;$File&quot;
  echo &quot;Ubuntu Mono 12&quot;
  echo &quot;\&quot;[...]${Results[$File]}[...]\&quot;&quot;
done | \
yad --list --listen --print-column=1 \
--expand−column=0 \
--title=&quot;$Title&quot; \
--text=&quot;$TxtMain&quot; \
--ellipsize=NONE \
--width=800 --height=600 --center \
--dclick-action=&quot;bash -c \&quot;open_result %s\&quot; &amp;&quot; \
--column=&quot;File&quot;:TEXT --column=@font@ --column=&quot;Result&quot;:TEXT

}

open_result(){ xdg-open "$1" }

Prep

TOP_PID="$$"

SearchState="$(mktemp -u --tmpdir "${0##*/}.XXXXX")" echo "0" > "$SearchState"

export -f open_result

Cleanup

trap "echo "1" > "$SearchState"; sleep 1; [[ -f "$SearchState" ]] && rm -r "$SearchState"; exit" EXIT

Main

dialog_options dialog_progress& odt_search dialog_results

Dependencies

ODT finder uses unoconv to convert LO documents to plain text. The GUI is based on yad, a powerful Zenity fork. Yad isn't available in the official repositories, yet, but you can install it from a webupd8 PPA.

The following commands should take care of all dependencies:

sudo add-apt-repository ppa:webupd8team/y-ppa-manager
sudo apt-get update
sudo apt-get install unoconv yad

Installation

Copy and paste the contents of the code box above into a new text file, name it whatever you want and make it executable. You can integrate the script with your system in various ways, e.g. by assigning a launcher or using it as a Nautilus script.

Usage

First time launching the script you will be greeted with an entry dialog for the folder you want to search through and the search term:

enter image description here

Click on 'OK' to start the query. This might take a while:

enter image description here

When the result window pops up you can double-click on any of the entries to open it in your default viewer (LibreOffice, generally). You can do this for more than one file:

enter image description here

The script will exit after hitting OK, Cancel, or closing the window.

There are some basic checks to guide the user and warn them if something went wrong:

enter image description here

enter image description here

Hopefully this fits the bill ☺.

Glutanimate
  • 21,393