LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-30-2007, 09:07 AM   #1
chess
Member
 
Registered: Mar 2002
Location: 127.0.0.1
Distribution: Slackware and OpenBSD
Posts: 740

Rep: Reputation: 190Reputation: 190
Find and Grep in Script - almost there


Hi - I need a bit of help with the final piece of a little bash script.

I need to traverse through a directory and its subdirectories looking for files that end with .txt. I need to grep through the found .txt files and print out a particular line, followed by the path and filename of the file itself.

For starters, from a terminal, when I do this:

Code:
find . -name *.txt | xargs grep metadate*
it almost works. I get the following output, as an example:

./directory/filename.txt:metadate20061212

What I need is for the metadate to come first, then the file location and name like this:

metadate20061212:./directory/filename.txt

Here is script I have so far:

Code:
#!/bin/sh
for i in $(find . -name *.txt); do
cat $1 | grep meta*;
echo $i;
done
This works, but it inserts a line break after the cat, so the output is like this:

metadate20061212
./directory/filename.txt

If someone could help me tweak the script so it outputs everything on one line I would be very appreciative. Or if there is a better way to do this, I would love to know it -- learning BASH never ends.

Thanks!
 
Old 04-30-2007, 09:25 AM   #2
radoulov
Member
 
Registered: Apr 2007
Location: Milano, Italia/Варна, България
Distribution: Ubuntu, Open SUSE
Posts: 212

Rep: Reputation: 38
Assuming GNU grep on Linux:

Code:
sed 's/\(.*\):\(.*\)/\2:\1/' <(grep -rF meta --include="*.txt" *)
or:

Code:
while IFS=: read a b;do echo "$b":"$a"; done< <(grep -rF meta --include="*.txt" *)

Last edited by radoulov; 04-30-2007 at 09:38 AM.
 
Old 04-30-2007, 09:56 AM   #3
Nathanael
Member
 
Registered: May 2004
Location: Karlsruhe, Germany
Distribution: debian, gentoo, os x (darwin), ubuntu
Posts: 940

Rep: Reputation: 33
find . -name *.txt | xargs grep metadate* | awk -F ':' '{print $2 "\n" $1 "\n"}'
 
Old 04-30-2007, 11:36 AM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
how about
Code:
find . -name "*.txt" -exec grep "metadate*" {} \;
--- rod.
 
Old 04-30-2007, 05:48 PM   #5
cfaj
Member
 
Registered: Dec 2003
Location: Toronto, Canada
Distribution: Mint, Mandriva
Posts: 221

Rep: Reputation: 31
Quote:
Originally Posted by Jackson1995
Hi - I need a bit of help with the final piece of a little bash script.

I need to traverse through a directory and its subdirectories looking for files that end with .txt. I need to grep through the found .txt files and print out a particular line, followed by the path and filename of the file itself.

For starters, from a terminal, when I do this:

Code:
find . -name *.txt | xargs grep metadate*
it almost works. I get the following output, as an example:

./directory/filename.txt:metadate20061212

What I need is for the metadate to come first, then the file location and name like this:

metadate20061212:./directory/filename.txt

Here is script I have so far:

Code:
#!/bin/sh
for i in $(find . -name *.txt); do

That will fail if there are any .txt files in the current directory; quote the pattern.

It will also fail if any filenames contain spaces.
Quote:
Code:
cat $1 | grep meta*;

That will also fail if any filenames contain spaces, or if any files in the current directory begin with "meta".
Quote:
Code:
echo $i;
done
This works, but it inserts a line break after the cat, so the output is like this:

metadate20061212
./directory/filename.txt

If someone could help me tweak the script so it outputs everything on one line I would be very appreciative. Or if there is a better way to do this, I would love to know it -- learning BASH never ends.

Assuming GNU (and some other versions of) find and xargs:
Code:
find . -name '*.txt' -print0 |
 xargs grep "meta*" /dev/null |
  awk -F: '{ print $2 ":" $1 }'
Note that that will fail if any filenames contain a colon, or if a found line contains a colon.

 
Old 05-01-2007, 02:32 AM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,349

Rep: Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750
something like this ?

Code:
for file in `find . -name '*.txt'`
do
    rslt=`grep 'meta*' $file 2>/dev/null`
    if [[ $? -eq  0 ]]
    then
        echo $rslt|awk -F: '{ print $2 ":" $1 }
    fi
done
 
Old 05-01-2007, 02:32 AM   #7
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,349

Rep: Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750Reputation: 2750
something like this ?

Code:
for file in `find . -name '*.txt'`
do
    rslt=`grep 'meta*' $file 2>/dev/null`
    if [[ $? -eq  0 ]]
    then
        echo $rslt|awk -F: '{ print $2 ":" $1 }
    fi
done
EDIT: aaarrggghh; problem with my connection. Can some kind moderator remove this duplicate post.? Thx

Last edited by chrism01; 05-02-2007 at 01:20 AM.
 
Old 05-01-2007, 02:51 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
for safety you should always quote when using the -name option

-name '*.txt'


so the glob isn't expanded by the shell for instance if you have a *.txt in your
current working directorry.
 
Old 05-01-2007, 09:15 AM   #9
chess
Member
 
Registered: Mar 2002
Location: 127.0.0.1
Distribution: Slackware and OpenBSD
Posts: 740

Original Poster
Rep: Reputation: 190Reputation: 190
Wow, thanks for all the great responses. Clearly, I have a lot of Bash learning to do. :-)

Anyway, I ended up using radoulov's second piece of code:

Code:
while IFS=: read a b;do echo "$b":"$a"; done< <(grep -rF meta --include="*.txt" *)
and just piped that to a text file. Worked great.

Thanks again, everyone. This has been very helpful and educational.
 
  


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
bash script with grep and sed: sed getting filenames from grep odysseus.lost Programming 1 07-17-2006 11:36 AM
using find /grep gamor Linux - Newbie 14 04-13-2005 02:36 PM
find with grep and replace it dominant Linux - Newbie 4 03-03-2004 01:11 PM
help me find grep-2.5.1 shanenin Linux - Software 1 01-23-2004 09:01 PM
trying to use find and grep, but don't know well enough. duhduhdude Linux - Newbie 9 03-22-2003 08:44 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:13 PM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration