4

I'm not very experienced in shell scripting, but I'm trying to understand how to grep for a pattern and for each file where there is a match write a file to disk that contains the matched line from grep. For example:

$ grep -E "MY PATTERN" myfile{1,3}

Then write out new files that contain the matching lines:

matches-myfile1
matches-myfile2
matches-myfile3

Is this possible? How can I do this? I'm looking for an answer is bash or zsh.

5 Answers 5

6

Bonsi has the right idea, but not the right approach (what should one do with filenames containing spaces or other whitespace characters, for example). Here is a way of doing it in bash:

for file in myfile{1,3}; do
    grep -E "MY PATTERN" < "$file" > "matches-$file"
done

If you did need to store the files you should account properly for word splitting, like so:

files=( myfile{1,3} )
for file in "${files[@]}"; do
    grep -E "MY PATTERN" < "$file" > "matches-$file"
done
2
  • 1
    I fixed that flaw in his approach
    – jordanm
    Commented Nov 9, 2012 at 15:46
  • Note that a difference with @Guru's approach is that if "MY PATTERN" is not to be found in myfile2 or if myfile2 doesn't exist or is not readable, then a matches-myfile2 will still be created (empty). Commented Nov 10, 2012 at 20:17
6

One way using awk:

awk '/MY PATTERN/{print > "matches-"FILENAME;}' myfile{1,3}
2

i don't think that this is possible however it is possible to build a small script for that

#! /bin/bash
files=(file1 file2 file3)
for i in "${files[@]}"; do grep -E "MY PATTERN" < "$i" > matches-"$i"; done
0
2

You can do it like this with GNU find and GNU parallel:

find . -type f -print0 | parallel -0 grep '"MY PATTERN"' '{} > {//}/matches.{/}'
1

You can make grep output the filename with -H, and then use awk to write to it.

$ grep -H regexp files*  | awk -F : '{ file="matches-" $1; sub("^[^:]+:","",$0); print $0 > file; }'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .