Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:


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

share|improve this question
up vote 6 down vote accepted

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"

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"
share|improve this answer
I fixed that flaw in his approach – jordanm Nov 9 '12 at 15:46
and thanks for that. :) – Bonsi Scott Nov 9 '12 at 15:55
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). – Stéphane Chazelas Nov 10 '12 at 20:17

One way using awk:

awk '/MY PATTERN/{print > "matches-"FILENAME;}' myfile{1,3}
share|improve this answer

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
share|improve this answer
Thanks for the edit. :) – Bonsi Scott Nov 9 '12 at 15:56

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

find . -type f -print0 | parallel -0 grep '"MY PATTERN"' '{} > {//}/matches.{/}'
share|improve this answer

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; }'
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.