2

My script is not matching exact words only. Example: 12312312Alachua21321 or Alachuas would match for Alachua.

KEYWORDS=("Alachua" "Gainesville" "Hawthorne")
IFS=$'\n'
find . -size +1c -type f ! -exec grep -qF "${KEYWORDS[*]}" {} \; -exec truncate -s 0 {} \;
  • I tried adding -x that doesn't work. – Guest in need of help Jan 15 '14 at 20:51
  • Your issue here is that you want to use -w (see my answer) but in future, please show us example input and desired output. Saying that "it does not work" is not very useful. – terdon Jan 15 '14 at 21:05
3

You have not told us what you actually want to do. I am assuming that you want to truncate those files that do not contain any of your keywords (at least that's what it looks like).

If you want grep to match whole words only, use the -w flag. From man grep:

   -w, --word-regexp
          Select  only  those  lines  containing  matches  that form whole
          words.  The test is that the matching substring must  either  be
          at  the  beginning  of  the  line,  or  preceded  by  a non-word
          constituent character.  Similarly, it must be either at the  end
          of  the  line  or  followed by a non-word constituent character.
          Word-constituent  characters  are  letters,  digits,   and   the
          underscore.

In addition, grep cannot take multiple patterns as arguments. Your command will be expanded by bash to

grep -qF Alachua Gainesville Hawthorne

This means "search for Alachua in the files Gainesville and Hawthorne". In order to pass multiple patterns to grep you need to either separate them with | (you'll need to activate extended regular expressions with-E) or save them into a file and pass that file to grep using -f:

   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

For example, in your script you could create a temporary file, save the patterns into it and then grep (there is no reason to set IFS here):

#!/usr/bin/env bash

KEYWORDS=("Alachua" "Gainesville" "Hawthorne")

## Create a temporary file
tmp=$(mktemp);

## Save your keywords in that file
for word in "${KEYWORDS[@]}"; do
    echo $word >> "$tmp";
done

## Now run your find command and tell grep
## to read the patterns from the temp file
find . -size +1c -type f ! -exec grep -qwFf "$tmp" {} \; -exec truncate -s 0 {} \;

Alternatively, build your pattern by joining your strings of interest with | and run grep with -E for extended regular expressions:

#!/usr/bin/env bash

patterns="Alachua|Gainesville|Hawthorne";
find . -size +1c -type f ! -exec grep -Eqw "$patterns" {} \; -exec truncate -s 0 {} \;
  • @slm thanks, almost as long as one of yours :). – terdon Jan 15 '14 at 21:41
  • ouch........... 8-) – slm Jan 15 '14 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.