General Computing
linux search grep string whitespace
Updated Sat, 23 Jul 2022 13:00:05 GMT

Search recursively for a string containing whitespaces


I want to search for "this table..." string under /home/myuser directory recursively, ie in all files under /home/myuser and in all directories and sub-directories under /home/myuser.

/home/myuser directory is set to a environment variable: $MYUSR

The search must be case insensitive, and it should give me the full path name of the files containing "this table..." string.

I try:

grep -R "this table..." $MYUSR

but I'm not sure if it really searches because I wait for a long time and it does not return any result and it never ends.

I also want to know how to do the same search recursively in the directory I'm standing in, maybe like:

grep -R "this table..." .

How do I do it?




Solution

  find $MYUSR -type f -print0 | xargs -0 -n 10 grep -i -l 'this table...'

The options to find are

  • -type f - we don't want to search directories (just files in them), devices etc
  • -print0 - we want to be able to handle filenames containing spaces

The options to xargs are

  • -0 - Because of find -print0
  • -n 10 - Run grep on 10 files at a time (useful when not using grep's -l)

The options to grep are

  • -i - ignore case
  • -l - just list filenames (not all matching lines)
  • -f - treat dots in search expression as plain ol' dots.

To start in the current directory replace $MYUSR with .


Update (a fellow superuserer suggested find -type f -exec grep -i "this table..." +)

$ ls -1
2011
2011 East
2011 North
2011 South
2012
$ find -type f -exec grep -i 'this table...'
find: missing argument to `-exec'
$ find -type f -exec grep -i 'this table...' +
find: missing argument to `-exec'
$ find -type f -exec grep -i 'this table...' {} \;
this table... is heavy
THIS TABLE... is important
this table... is mine
this table... is all alike
this table... is twisty

But that's not useful, you want filenames

$ find -type f -exec grep -i -l 'this table...' {} \;
./2011 East
./2011
./2011 North
./2011 South
./2012

OK but often you want to see the matching line content too

If you want filenames AND matching line content, I do it this way:

$ find -type f -print0 | xargs -0 -n 10 grep -i 'this table...';
./2011 East:this table... is heavy
./2011:THIS TABLE... is important
./2011 North:this table... is mine
./2011 South:this table... is all alike
./2012:this table... is twisty

But without "old skool" -print0 and -0 you'll get a mess

$ find -type f | xargs -n 10 grep -i 'this table...';
./2011:THIS TABLE... is important
grep: East: No such file or directory
./2011:THIS TABLE... is important
./2011:THIS TABLE... is important
grep: North: No such file or directory
./2011:THIS TABLE... is important
grep: South: No such file or directory
./2012:this table... is twisty




Comments (5)

  • +0 – Thanks. What is the meaning of 10 ? — Mar 26, 2012 at 13:51  
  • +0 – And How do I make the same search i the directory im standing in? — Mar 26, 2012 at 13:51  
  • +0 – @alwbtc: See updated answer — Mar 26, 2012 at 14:01  
  • +0 – No need all of this old school tricks : find -type f -exec grep -i "this table..." + is sufficient. — Mar 26, 2012 at 14:02  
  • +0 – @sputnick: on my system, find complains: "find: missing argument to '-exec'" unless you add {} \; also you need grep's -l option otherwise it doesn't show filenames. If you want to see matches AND filenames you probably need xargs in the mix (or some equivalent options) — Mar 26, 2012 at 14:30