Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

INPUT:

Select ASDF 325 sdfg sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg sdfg 4456 sdrg

OUTPUT:

Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg

So in short I need to "sed" "sdfg" to "XXXX".

BUT: only in lines that contains the "Select ASDF" string.. How can I do this? (sed, awk, etc. :\ )

share|improve this question

3 Answers 3

up vote 11 down vote accepted

You can prefix most sed commands with an address to limit the lines to which they apply. An address can be a line number, or a regex delimited by /.

cat INPUT | sed '/Select ASDF/ s=sdfg=XXXX='

As mentioned Peter.O, the command as written above will substitute the first occurrence of any sdfg in the string containing Select ASDF. If you need to substitute the exact match to sdfg only in the case it is in fourth column you should go this way:

cat INPUT | sed 's/\(^Select ASDF [^ ]* \)sdfg /\1XXXX /'
share|improve this answer
1  
What about another field containing sdfg? eg. 5sdfga –  Peter.O Apr 28 '12 at 10:39
    
Hmm, actually that's not the problem too. I've updated my answer. –  rush Apr 28 '12 at 11:01
    
are there any options for using: sed '/Select ASDF/g s=sdfg=XXXX=' - so I need to replace all the occurences in a line, not just the first one. but sed gives error if I use "g" –  LanceBaynes May 4 '12 at 9:28
    
You need to type g after last = (at the end of s command). It will be like this: sed '/Select ASDF/ s=sdfg=XXXX=g' –  rush May 4 '12 at 10:00

If you're only changing column 4 if it has the exact value, then using equality operators instead of regular expressions makes sense.

awk '$1 == "Select" && $2 == "ASDF" && $4 == "sdfg" {$4 = "XXXX"} {print}'
share|improve this answer
    
Fast! .. comparing it, for 1 million lines, with Birei's awk and Rush's positional sed: 0m1.580s vs. 0m3.792s vs. 0m6.740s –  Peter.O Apr 28 '12 at 16:22

Using GNU awk:

awk '
    BEGIN { IGNORECASE = 1 } 
    /^select asdf/ { 
        sub( /\<sdfg\>/, "XXXX", $0 ) 
    } 
    { print }
' infile

Output:

Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg

UPDATE: Avoid IGNORECASE for a non-GNU awk, and match case-sensitive. Thanks to jw013, who pointed out that detail:

awk ' 
    /^Select ASDF/ { 
        sub( /\<sdfg\>/, "XXXX", $0 ) 
    } 
    { print }
' infile
share|improve this answer
1  
You should mention IGNORECASE is a GNU awk / gawk extension. –  jw013 Apr 28 '12 at 8:06
1  
@jw013: Thank you. Updated answer with your suggestion. –  Birei Apr 28 '12 at 8:40
4  
IGNORECASE is wrong in this case, whether it's GNU or G'not.. The criterion in the question is explicitly for upper-case ASDF –  Peter.O Apr 28 '12 at 10:49

Your Answer

 
discard

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.