I am trying to replace a part of a pattern, such as, if I have col(3,B,14), after applying the sed command, I would like to get col(3,B,t14) which adds the t character to the third parameter in the pattern.
I am trying with :
s="col(3,B,14)"
echo $s | sed 's/col([0-9],[A-Z],[0-9])/col([0-9],[A-Z],t[0-9])/g'But, it returns the original string. I would appreciate it if you could give some advice. Thanks.
21 Answer
You seem a bit confused about how sed works, so I'll go step by step. My "answer" is this:
s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'Explanation
There are a couple of problems here.
First, you need a semicolon (
;) after defining your variables, beforeechoing it.s="col(3,B,14)"; echo $sNext,
sedsubstitution works bys/pattern/replacement/, wherepatternis a regular expression, but wherereplacementis not. That is, putting something like[0-9]in thereplacementwill not represent any digit, but will instead represent the five characters:[,0,-,9, and].Also, the
/gat the end is used to keep applying the substitution on a string for every match of the pattern, so if you had a line like:echo hello world | sed 's/o/z/g'then the output would be:
hellz wzrldwhereas:
echo hello world | sed 's/o/z/'would give:
hellz worldLet's remove your replacement for now:
s="col(3,B,14)"; echo $s | sed 's/col([0-9],[A-Z],[0-9])/replacement/g'Turning attention to the regular expression pattern you used, it says "match a string like
col(\<single digit>,\<uppercase letter>,\<single digit>)". Notice that the last[0-9]piece won't match14, since14is a two-digits number and so your pattern would matchcol(3,B,1), but will not matchcol(3,B14). To match one or more digits, you can use[0-9][0-9]*.To do the replacement as you want, the best way would be to use a capture group. Capture groups "remember" part of the match for later use. You put
\(and\)around the part of the pattern you want to remember and use\1to refer to it later:s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1replacement/g'This will match
col(\<single digit>,\<uppercase letter>,, so up to and including the point where you want to add at. All of this matched stuff will be put back in the replacement (\1) followed by any text you add (in this case we're adding the literal text "replacement"). Any remaining text not matched in the input will be unaffected. The above will output:col(3,B,replacement14)So if we now put a "t" in the
replacementstring:s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'we get:
col(3,B,t14)
If you want to learn sed well, I can recommend an excellent tutorial: