Replacing a particular position in a file
Hi,
I have a file content as follows. The file content has got 5 columns each separated by ':' as field separator. I want to replace the value in the second column. ie if a value in second column is 333331 I have to replace with 777771. But if 333331 is in first or someother column other than 2nd column then it should not be replaced. Anyway to do this in Sed or AWK?? The file content as follows: "33333110000":"333331238283":NULL:0:3 "33333110000":"444441001362":NULL:1:2 "9880222221":"333331708559":NULL:0:3 "9880222221":"333331001362":NULL:1:2 "9880222221":"444441001362":NULL:2:2 "9880222222":"333331414216":NULL:0:3 "9880222223":"333331858924":NULL:0:3 "9880222223":"333331001362":NULL:1:2 "9880222224":"333331803679":NULL:0:3 "9880222224":"333331001362":NULL:2:2 "9880333331":"333331733603":NULL:0:3 "9880333331":"444441001362":NULL:3:2 333331 in the second column should be replaced but 333331 in first column should not be replaced. Thanks!! |
Ok one way of doing it will be
I`ve replaceed 333331 with OOO cat filename | sed "s/^\([^:]*:[^:]*\)333331\([^:]*:\)/\1OOO\2/" But the above regex is too long I`m trying for a better one Cheers Z |
Hey Z,
I'm studying linux and am having trouble understanding the sed command you detailed. It works. I tried it, but I don't understand it. Here's my comprehension of the command (skipping over the cat portion): 1. s initiates a substitute operation. 2. ^ starts the search a beginning of the lines/strings 3. /(/) sequence places column A : column B into a buffer. 4. The first argument of the substitute operation is provided "33331" 5. Then /(/) places the first column of characters into a buffer. (again?) 6. The second argument of the substitute command is provided "\1000\2\/" This portion seems to say, recall buffer #1 and replace 33331 of the buffered data with 000, and then it recalls buffer 2. I know I've taken a wrong turn in my thinking here. Would you be kind enough to point me to where I skipped track? Also I would think that the command would need to end with /g. Thanks |
Token by token:
sed -- you got that right :) s/ -- substitute the following with FOO ^ -- beginning of line \( -- begin group (which you call buffer) [^:]* -- match any number of any char that's not a colon; `*' means any number of (what preceeds it); [^abcd] means "anything except abcd" (in this case it's just `:'). : -- then match a colon [^:]* -- then match any no. of not-colon again \) -- end group 1 333331 -- the text you want to be replaced with (some other text). \([^:]*:\) -- should be more or less obvious / -- # FOO begins here \1 -- the contents of group 1 (i.e. everything up until 333331) OOO -- the replacement text. \2 -- the rest of the line. / -- # FOO ends here Quote:
I think this is more elegant, more correct and possibly faster too: Code:
$ sed -r 's/^([^:]*:)333331/\1777771/' filename If all else fails, RTM :D hth --Jonas |
zulfilee's answer worked ..
|
Ok here is a better one
awk 'BEGIN{FS=":";OFS=":"} {gsub("333331","AAAA",$2); print $0}' filename BEGIN -> Start of script FS,OFS are input and output field seperators. [By default awl takes space as field separator] gsub is a function which has this format gsub(Pattern,Replacement,StringPosition) And print $0 will printout the output awk -F ":" '{gsub("333331","AAAA",$2); print $0}' filename will also work . Here we specify the filed seperator outside [But ideally sub should be used instead of gsub. gsub is global substitution] Cheers Z |
Hi Z and everyone,
My file content is "4444412000 ":"444441001362":"Kodiak2Grp " "9880222221 ":"333331001362":"TestGrp1 " "3333312221 ":"333331333331":"TestGrp1 " The file has three fields....I have to replace 333331 in the second column only...the script If the first 6 characters match the string then only it should be replaced..[if the last 6 or the any combination of six characters in the second column matches other than first 6 characters, then it should not be replaced].. |
sed 's/^\([^:]*:"\)333331\([^:]*:\)/\1AAAA\2/' filename
Ive just removed the [^:]* and put a explicit " to the previous sed command.Means look for the first 6 chars In awk it`ll be a bit long awk -F ":" '{if ($2 ~ /^"333331/) {sub("333331","AAA",$2) ;print $0} else {print $0}} ' filename Here we check if second string [: separated ] is staring with 33331 Or we print the line as it is. You can write it more shortly too Cheers Z |
thanks..
|
sed "s/^\([^:]*:\"\)$oldtr\([^:]*:\)/\1$newstr\2/"
SIngle quotes will mask the variable and try to serach is as $oldstr and not 333331 Just go for double quotes but then you have to escape the doulbe quote inside search with a backslash i.e \" Cheers Z |
How to replace the string '33331' which comes in the beginning of 7th column alone has to be replaced...other 333331 in other columns should be retained as such..
2:"333331333331333331":"333331333331333331":"333331":1:1:1:"333331333331":"333331333331333331":1:1 12:"333331333331333331":"222221222221222221":"222221":1:1:1:"222221222221":"222221222221222221":1:1 12:"222221222221222221":"333331333331333331":"222221":1:1:1:"222221222221":"222221222221222221":1:1 12:"222221222221222221":"222221222221222221":"222221":1:1:1:"333331333331":"222221222221222221":1:1 12:"222221222221222221":"222221222221222221":"222221":1:1:1:"222221222221":"333331333331333331":1:1 12:"222221222221222221":"222221222221222221":"222221":1:1:1:"222221222221":"222221222221222221":1:1 12:"333331222221222221":"333331333331222221":"222221":1:1:1:"333331333331":"222221222221222221":1:1 12:"333331222221222221":"333331333331222221":"222221":1:1:1:"222221222221":"333331333331222221":1:1 |
The same awk script can be used as such
awk -F ":" '{if ($8 ~ /^"333331/) {sub("333331","AAA",$8) ;print $0} else {print $0}} ' filename The pattern was in the 8 th column In sed sed 's/^\(\([^:]*:\)\{7\}\)"333331\(..*\)/\1"AAAA\3/' filename ^\(\([^:]*:\)\{7\}\) -> Here we Look for a pattern that comes as something:something 7 times. "333331 -> Then we search for the string in the 8th field \(..*\) -> The rest of the line \1 -> is the first \( \) enclosure and \3 is the last. But in sed it doesnt look that good. Cheers Z |
If I used AWK then the field separator disappears for those rows where the values were replaced...why is it so??
Output comes like this... 12 "333331333331333331" "333331333331333331" "333331" 1 1 1 "AAA333331" "333331333331333331" 1 1 12:"333331333331333331":"222221222221222221":"222221":1:1:1:"222221222221":"222221222221222221":1:1 12:"222221222221222221":"333331333331333331":"222221":1:1:1:"222221222221":"222221222221222221":1:1 12 "222221222221222221" "222221222221222221" "222221" 1 1 1 "AAA333331" "222221222221222221" 1 1 12:"222221222221222221":"222221222221222221":"222221":1:1:1:"222221222221":"333331333331333331":1:1 12:"222221222221222221":"222221222221222221":"222221":1:1:1:"222221222221":"222221222221222221":1:1 12 "333331222221222221" "333331333331222221" "222221" 1 1 1 "AAA333331" "222221222221222221" 1 1 12:"333331222221222221":"333331333331222221":"222221":1:1:1:"233333122221":"333331333331222221":1:1 Command: awk -F ":" '{if ($8 ~ /^"333331/) > {sub("333331","AAA",$8) ;print $0} > else {print $0}} ' Any ideas?? |
Oops sorry then try this
awk 'BEGIN {FS=":";OFS=":"} {if ($8 ~ /^"333331/) > {sub("333331","AAA",$8) ;print $0} > else {print $0}' filename What happenned was awk has default OFS[o/p file seperator ] as space this has replaced your orginal fs ":" Cheers Z |
Thanks for the info(OFS)...Gr88
|
All times are GMT -5. The time now is 01:34 AM. |