I'm using this to delete lines that don't match a pattern:

$ egrep "pattern1|pattern2|pattern3|pattern4|pattern5"

But now I need to do it automatically, so I'm setting a variable like this:

$ catTMP=~/mpp/*.xml

And I want to run something like this:

$ egrep "pattern1|pattern2|pattern3|pattern4|pattern5" $catTMP > $catTMP.2

How would I base the redirect name off of what variable already exists? If you still don't understand, I mean something like this:

$ cd ~/mpp/
$ ls

$ egrep "pattern1|pattern2|pattern3|pattern4|pattern5" $catTMP > $catTMP.2

$ ls
x.xml x.xml.2

Or even better would be in place editing, but grep can't do that, so maybe there is a way to do this with another command, and just do something like -i.


Edit in place, keeping only lines that match the pattern:

sed -n -r -i "/(pattern1|pattern2|pattern3|pattern4|pattern5)/p" ~/mpp/*.xml

On BSD sed (Mac OSX), try:

sed -n -E -i '' "/(pattern1|pattern2|pattern3|pattern4|pattern5)/p" ~/mpp/*.xml

Basing the file name off of an already existing variable

for fname in ~/mpp/*.xml
    egrep "pattern1|pattern2|pattern3|pattern4|pattern5" "$fname" > "$fname.2"

The above works because a period is not legal in a variable name. Consequently, the shell knows that, in $fname.2, the variable name is just fname. If that is not case, then curly braces are required. For example:

for fname in ~/mpp/*.xml
    egrep "pattern1|pattern2|pattern3|pattern4|pattern5" "$fname" > "${fname}_2"

Here, the curly braces make clear to the shell that the variable name is fname, not fname_2.

  • Im using BSD sed, just checking before if it works on BSD sed? – DisplayName Nov 1 '14 at 23:44
  • @DisplayName Thanks for the update. There are two possible issues. One is that -r should be replaced with -E. The other is that some versions of sed require that an argument be given for -i. – John1024 Nov 1 '14 at 23:46
  • Yeah, i usually use -i '' – DisplayName Nov 1 '14 at 23:46
  • @DisplayName If this answer solved your problem, please consider marking it Accepted so that others browsing the site know that this question has been answered. – Joseph R. Nov 2 '14 at 8:02
  • Yeah i usually do that. It did solve my question, but since it doesn't answer what the title says I'm not sure if the people looking for how to do this will be happy with the answer. – DisplayName Nov 2 '14 at 15:59

using awk

for x in `ls ~/map/*.xml`;do awk '/(pattern1|pattern2|pattern3|pattern4|pattern5)/{print}' $x > $x.2; done

the for will loop over all xml file and awk find pattern , if matched will store in .xml.2


You can use grep like:

for f in /dir/*glob*
do  grep -E 'pattern|list' <<INFILE >"$f"
$(cat "$f")

It will drop any trailing blank lines from each file in $f but my assumption was that blank lines were probably not among your pattern|list anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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