Unix Shell - Sed to match multiple patterns

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > November 2005 > Sed to match multiple patterns





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Sed to match multiple patterns
solaris9000

2005-11-25, 7:49 am

Hello

I have got a file called "filename" like this:

#
#
path1 something1
#
path2 something2
#

I'd like to append "flag" to each line beginning path1 and path2 so the
file becomes:

#
#
path1 something1 flag
#
path2 something2 flag
#

I'd like to use sed for this. So far I can only match one pattern at a
time in sed. eg

sed '/path1/ s/$/ flag/' filename
sed '/path2/ s/$/ flag/' filename

Is there anyway I can combine both patterns in one line?

eg sed '/pattern1/ && /pattern2/ s/$/flag/' filename - I know this
doesnt work.

Thanks in advance.

Ed Morton

2005-11-25, 5:53 pm

solaris9000 wrote:
> Hello
>
> I have got a file called "filename" like this:
>
> #
> #
> path1 something1
> #
> path2 something2
> #
>
> I'd like to append "flag" to each line beginning path1 and path2 so the
> file becomes:
>
> #
> #
> path1 something1 flag
> #
> path2 something2 flag
> #
>
> I'd like to use sed for this. So far I can only match one pattern at a
> time in sed. eg
>
> sed '/path1/ s/$/ flag/' filename
> sed '/path2/ s/$/ flag/' filename


sed '/path\(1\|2\)/ s/$/ flag/' filename

or

sed '/\(path1\|path2\)/ s/$/ flag/' filename

Ed.
Icarus Sparry

2005-11-25, 5:53 pm

On Fri, 25 Nov 2005 08:36:11 -0600, Ed Morton wrote:

> solaris9000 wrote:
>
> sed '/path\(1\|2\)/ s/$/ flag/' filename
>
> or
>
> sed '/\(path1\|path2\)/ s/$/ flag/' filename
>
> Ed.


This works with GNU sed, but not with some others. The \| construct is the
problem. sed is only required to work with 'Basic Regular Expressions'
(BRE)

The OP can use ';' to put more than one command into the first argument,
or he can use multiple '-e' flags, e.g.

sed '/path1/s/$/ flag/;/path2/s/$/ flag/' filename
or
sed -e '/path1/s/$/ flag/' -e '/path2/s/$/ flag/' filename

Stephane CHAZELAS

2005-11-25, 5:53 pm

2005-11-25, 08:36(-06), Ed Morton:
[...]
>
> sed '/path\(1\|2\)/ s/$/ flag/' filename
>
> or
>
> sed '/\(path1\|path2\)/ s/$/ flag/' filename

[...]

That's not standard. sed uses basic regexp and "\|" is not in
basic regexps as specified by the Single Unix Specification
(version 3 at least)

sed '
/^path1/{
s/$/flag/
b
}
/^path2/ s/$/flag/'

or

awk '
/^path1/ || /^path2/ {$0 = $0 "flag"}
{print}'

--
Stéphane
Bill Marcum

2005-11-25, 5:53 pm

On 25 Nov 2005 04:41:44 -0800, solaris9000
<solaris9000@gmail.com> wrote:
> Hello
>
> I have got a file called "filename" like this:
>
> #
> #
> path1 something1
> #
> path2 something2
> #
>
> I'd like to append "flag" to each line beginning path1 and path2 so the
> file becomes:
>
> #
> #
> path1 something1 flag
> #
> path2 something2 flag
> #
>
> I'd like to use sed for this. So far I can only match one pattern at a
> time in sed. eg
>
> sed '/path1/ s/$/ flag/' filename
> sed '/path2/ s/$/ flag/' filename
>
> Is there anyway I can combine both patterns in one line?
>

sed -e '/path1/ s/$/ flag/' -e '/path2/ s/$/ flag/' filename

--
Nothing so needs reforming as other people's habits.
-- Mark Twain, "Pudd'nhead Wilson's Calendar"
xicheng

2005-11-25, 5:53 pm

solaris9000 wrote:
> Is there anyway I can combine both patterns in one line?
> eg sed '/pattern1/ && /pattern2/ s/$/flag/' filename - I know this
> doesnt work.

use one pattern with "|" to group two, like:
sed -e '/pattern1\|pattern2/ s/$/ flag/' filename
XC

xicheng

2005-11-25, 5:53 pm


solaris9000 wrote:
> Is there anyway I can combine both patterns in one line?
>
> eg sed '/pattern1/ && /pattern2/ s/$/flag/' filename - I know this
> doesnt work.


You may use "|" with the regex, like

sed -e '/pattern1\|pattern2/ s/$/flag/' filename

XC

xicheng

2005-11-25, 5:53 pm

> Is there anyway I can combine both patterns in one line?
> eg sed '/pattern1/ && /pattern2/ s/$/flag/' filename - I know this
> doesnt work.

you may use "|" to group them into a single pattern like:

sed -e '/pattern1\|pattern2/ s/$/flag/' filename

XC

dan.rickhoff@comcast.net

2005-11-26, 8:48 pm


print "aa xx
bb yy
cc zz" | sed -E 's/^(aa|cc).*/& flag/'
aa xx flag
bb yy
cc zz flag

Will Renkel

2005-11-27, 5:52 pm

What version of sed are you using?
I tried several versions and they dont take a -E option.
But I just tried -r and it works.


--
---------------------------------------------------------------
Will Renkel
Wheaton, Ill.
REGISTERD Linux User: 300583

---------------------------------------------------------------
dan.rickhoff@comcast.net wrote:
>
>print "aa xx
>bb yy
>cc zz" | sed -E 's/^(aa|cc).*/& flag/'
>aa xx flag
>bb yy
>cc zz flag
>

dan.rickhoff@comcast.net

2005-11-27, 5:52 pm


Will Renkel wrote:
> What version of sed are you using?


That "-E" option to sed is available on my Mac, OS 10.4.3.
I don't know how to determine the version of that sed, but one of the
lines listed by the command

$ strings /usr/bin/sed | fgrep '@(#)'

is:

@(#)PROGRAM:sed PROJECT:text_cmds-47 DEVELOPER:root BUILT:Sun Mar 20
15:40:03 PST 2005

On my Mac, the man page for sed says:

-E Interpret regular expressions as extended (modern) regular
expressions rather than basic regular expressions (BRE's).
The
re_format(7) manual page fully describes both formats.

I just glanced through that man page and also found:

STANDARDS
...
The -E, -a and -i options are non-standard FreeBSD extensions
and may not
be available on other operating systems.

I have UWIN on my Windows PC and its version of sed also supports the
"-E" option.

Regards,
Dan R.

John Savage

2005-11-27, 8:49 pm

"solaris9000" <solaris9000@gmail.com> writes:
>sed '/path1/ s/$/ flag/' filename
>sed '/path2/ s/$/ flag/' filename
>
>Is there anyway I can combine both patterns in one line?
>
>eg sed '/pattern1/ && /pattern2/ s/$/flag/' filename - I know this
>doesnt work.


To illustrate the most general method:
sed '/path1/ba;/path2/ba;b;:a;s/$/ flag/' filename

Can be abbrev slightly: sed '/path1/ba;/path2/!b;:a;s/$/ flag/' filename

Note: if path has a '/' anywhere in it, you need to escape it with '',
e.g., s/dir1\/dir2\/dir3/ flag/
--
John Savage (my news address is not valid for email)

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com