Why is my recursive grep not working?

1

I am in a parent directory and want to search for any ODT files (LibreOffice Writer) that contain the phrase "GWT" in them.

I'm on Ubuntu 12.04 desktop. From the terminal:

myUser@myMachine:~/sandbox$ pwd
/home/myUser/sandbox
myUser@myMachine:~/sandbox$ ls
cloudflip  doctrang  eclipse   lookslike  scripts       squirrel  warlib

All these file system objects (eclipse, scripts, etc.) are folders.

myUser@myMachine:~/sandbox$ grep -i -r "GWT" *.odt
grep: *.odt: No such file or directory

Where am I going arye here? Thanks in advance!

pnongrata

Posted 2013-11-29T18:36:41.290

Reputation: 2 212

1grep -i -r "GWT" \*.odt Since odt files are not plain text, I'm not really sure of the results accuracy. – Fiisch – 2013-11-29T18:39:57.300

Thanks @Fiisch (+1) - however same result with your suggestion... – pnongrata – 2013-11-29T18:48:59.993

1You are instructing grep to recursively search all directories with names ending in .odt, not to recurse through all directories and search only files ending with .odt. – n.st – 2013-11-29T18:55:12.133

Thanks @n.st (+1) - so....how do I do what I want it to do (see the first sentence of my question)? – pnongrata – 2013-11-29T18:56:54.750

n.st is right; I made a mistake, sorry :) this should do the trick find -name *.odt | xargs grep -i "GWT" – Fiisch – 2013-11-29T21:29:04.567

1@Fiisch You actually don't have to switch to find to solve this. grep offers some useful options for its recursive search. See --include, --exclude, and --exclude-dir in the man page. For example: grep -R --include '*.odt' -i 'GWT' * – dg99 – 2013-11-30T00:52:55.583

OR alternatively an even simpler variant - find -name *.odt -exec grep -i "GWT" {} + – davidgo – 2013-11-30T01:21:36.493

Yup, I know. Choice depends on what you are accustomed to. :) – Fiisch – 2013-11-30T12:28:37.090

Answers

3

ODT files are actually Zip files (see https://stackoverflow.com/questions/4957212/how-does-open-office-compress-its-files) you should be able to grep them with the zipgrep command with something like this:

find ~/sandbox -name "*.odt" -type f -print0 | xargs -0 zipgrep GWT

vanthome

Posted 2013-11-29T18:36:41.290

Reputation: 198

+1 for zipgrep, since ODT files are effectively compressed and simple grep won't do the trick. However, this won't show which ODT files contain the string. – Dennis – 2013-12-01T00:35:55.640

0

Assuming your using Bash 4, you can do the following:

shopt -s globstar
grep -i GWT **/*.odt
shopt -u globstar

When the shell option globstar is set, ** recursively matches all subdirectories of the current directory. The second shopt command unsets the command; this step is optional.

As @vanthome points out, grepping the ODT files won't do any good, since they're actually compressed. There are two inconveniences:

  1. The zipgrep command doesn't take more than one archive name as an argument, so you have to loop through all ODT files.
  2. zipgrep will print the matching line only (which can be very long in an ODT file), so you still won't know which files contain the string.

The following might achieve the desired results:

shopt -s globstar

for file in **/*.odt; do
    unzip -c "$file" | grep -iq GWT && echo "$file"
done

shopt -u globstar

The for loop goes through all ODT files in all subdirectories. For each file that is found, it unpacks its contents to STDOUT. Then, grep searches for the desired string without outputting anything (-q). If a match is found, grep returns 0 and the command after the logical AND (&&) gets executed, so the filename is echoed on the terminal.

Dennis

Posted 2013-11-29T18:36:41.290

Reputation: 42 934