LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 07-09-2008, 02:03 AM   #1
serutan
LQ Newbie
 
Registered: Oct 2007
Posts: 11

Rep: Reputation: 0
how does recursive grep work?


According to many sources (example: The Linux Cookbook 2nd Ed. p349) the command

grep -r sometext ~/doc/*.txt

should search for the string "sometext" in .txt files in the directory ~/doc and all its subdirectories. Yet on my system (Ubuntu heron) it only searches files in ~/doc, ignoring subdirectories. Neither -r nor -R seem to have any effect at all. What am I doing wrong?

serutan
 
Old 07-09-2008, 02:17 AM   #2
Mr. C.
Senior Member
 
Registered: Jun 2008
Posts: 2,529

Rep: Reputation: 59
You are thinking that grep "sees" the argument ~/doc/*.txt. It doesn't. The shell first does file name expansion before it ever starts grep running. So, grep sees whatever the wildcard pattern expands to. Add echo in front of grep, and you'll see what grep sees. Or add set -x one line before the grep.
 
Old 07-09-2008, 02:33 AM   #3
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
You can do
Code:
grep -r pattern ~/doc
Which will grep all files under ~/doc. If you need to search in only some files, then you can employ find to location the files and xargs to call grep on them:
Code:
find ~/doc -type f -name '*.txt' -print0 | xargs -0 grep pattern
The -print0 option to find and the -0 option to xargs are not necessary if you have sensibly named files (without spaces and other weird characters), but it's generally a good idea to use them, despite the extra typing.
 
Old 07-11-2008, 09:41 AM   #4
serutan
LQ Newbie
 
Registered: Oct 2007
Posts: 11

Original Poster
Rep: Reputation: 0
Thanks for the help. I understand that "grep -r pattern ~/doc" will search ~/doc and its subdirectories for files containing the pattern. I also see that as Mr. C. says, "~/doc/*.txt" expands to a list of files ending in .txt in the ~/doc folder only. I'm trying to figure out how to search a subset of files, for example *.txt, within a directory and all its subdirectories. The reason is that I have a subdirectory tree containing many very large media files and a few .txt files, and I want to search only the .txt files.

After more research I believe this has to be a 2-step process: find the files by matching name pattern, then search the found files for the string pattern. The following works for me:

find ~/doc -name "*.txt" | xargs grep -H "test"

If there is a simpler equivalent command I would still like to know. Back in my VMS days I'm pretty sure this type of search was easy.
 
Old 07-11-2008, 10:10 AM   #5
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
The xargs approach is the tried and tested way. If you find it too long-winded, you can easily write a little script, put it in your PATH. An alternative is to write a shell function and put it in your .bashrc file

Code:
rgrep () {
        if [ $# -ne 2 ]; then
                echo "Usage: rgrep pattern directory/[filepattern]"
                return 1
        fi

        file_pattern=""
        dir="."

        if [ -d "$2" ]; then
                dir="$2"
        else
                case "$2" in
                */*)
                        # looks like we have a pattern in a directory
                        file_pattern="${2##*/}"
                        dir="${2%/*}"
                        ;;
                *)
                        # looks like we only have a pattern (no directory)
                        file_pattern="$2"
                        ;;
                esac
        fi

        if [ "$file_pattern" != "" ]; then
                file_pattern="-name \"$file_pattern\""
        fi

        find "$dir" -type f $file_pattern -print0 |xargs -0 grep -H "$1"
}
Which you can use like this:
Code:
rgrep pattern /some/existing/dir
Which will searh for pattern in all files under /some/existing/dir and it's sub-directories.
Or like this:
Code:
rgrep pattern /some/place/*.txt
Which will search for pattern in all files whose name ends with ".txt" in /some/place or any of it's sub-directories.
 
Old 07-11-2008, 01:00 PM   #6
Mr. C.
Senior Member
 
Registered: Jun 2008
Posts: 2,529

Rep: Reputation: 59
Perhaps what you want is a slight change:

find ~/doc -name "*.txt" | xargs grep -l test | other_commands

eg.

find ~/doc -name "*.txt" | xargs grep -l test | sort -u
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ls with recursive option and file name doesn't work FromFPan2Fire Linux - Newbie 7 01-05-2010 10:21 AM
Sorting recursive 'ls' and 'grep' SirTristan Linux - Newbie 5 03-13-2008 02:39 PM
grep does not work in crontab script blizunt7 Linux - General 5 08-24-2007 02:19 PM
recursive grep xpucto Solaris / OpenSolaris 2 05-29-2007 09:57 AM
Recursive grep jimieee Linux - General 5 10-06-2003 10:13 AM


All times are GMT -5. The time now is 01:39 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration