use of remembered patterns \1, \2 in sed

Hi,
can you anyone shed some light on \1 \2 remembered patterns that are being used in sed command.
LVL 1
CharanRAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Rick_AtreidesCommented:
Yoe mean like this ?
>echo 'My Name is SedUser' | sed -r -e 's/My Name is (.+)$/Hello, \1/'
Hello, SedUser

Open in new window

0
ajay_mhasalCommented:
Hi,

If you want to modify a particular pattern that is not the first one on the line, you could use "\(" and "\)" to mark each pattern, and use "\1" to put the first pattern back unchanged. This example keeps the first word on the line but deletes the second:

    sed 's/\([a-zA-Z]*\) \([a-zA-Z]*\) /\1 /' <old >new

There is an easier way to do this. You can add a number after the substitution command to indicate you only want to match that particular pattern. Example:

    sed 's/[a-zA-Z]* //2' <old >new

You can combine a number with the g (global) flag. For instance, if you want to leave the first world alone alone, but change the second, third, etc. to DELETED, use /2g:

    sed 's/[a-zA-Z]* /DELETED /2g' <old >new

Don't get /2 and \2 confused. The /2 is used at the end. \2 is used in inside the replacement field.

Note the space after the "*" character. Without the space, sed will run a long, long time. (Note: this bug is probably fixed by now.) This is because the number flag and the "g" flag have the same bug. You should also be able to use the pattern

    sed 's/[^ ]*//2' <old >new

but this also eats CPU. If this works on your computer, and it does on some Unix systems, you could remove the encrypted password from the password file:

    sed 's/[^:]*//2' </etc/passwd >/etc/password.new

But this didn't work for me the time I wrote thise. Using "[^:][^:]*" as a work-around doesn't help because it won't match an non-existent password, and instead delete the third field, which is the user ID! Instead you have to use the ugly parenthesis:

    sed 's/^\([^:]*\):[^:]:/\1::/' </etc/passwd >/etc/password.new

You could also add a character to the first pattern so that it no longer matches the null pattern:

    sed 's/[^:]*:/:/2' </etc/passwd >/etc/password.new

The number flag is not restricted to a single digit. It can be any number from 1 to 512. If you wanted to add a colon after the 80th character in each line, you could type:

    sed 's/./&:/80' <file >new

You can also do it the hard way by using 80 dots:

    sed 's/^................................................................................/&:/' <file >new

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Shell Scripting

From novice to tech pro — start learning today.