LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Find and Grep in Script - almost there (https://www.linuxquestions.org/questions/programming-9/find-and-grep-in-script-almost-there-550128/)

chess 04-30-2007 09:07 AM

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!

radoulov 04-30-2007 09:25 AM

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" *)

Nathanael 04-30-2007 09:56 AM

find . -name *.txt | xargs grep metadate* | awk -F ':' '{print $2 "\n" $1 "\n"}'

theNbomr 04-30-2007 11:36 AM

how about
Code:

find . -name "*.txt" -exec grep "metadate*" {} \;
--- rod.

cfaj 04-30-2007 05:48 PM

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.


chrism01 05-01-2007 02:32 AM

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


chrism01 05-01-2007 02:32 AM

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

bigearsbilly 05-01-2007 02:51 AM

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.

chess 05-01-2007 09:15 AM

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.


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