Reputation: 71
I need help on how to write a SED one liner (no awk) that replaces a substring of one line with a pattern in the same length. For example, if the file looks like:
daemon www X=1 ***Y=1,2,2*** Z= daemon www X=1 ***Y=1,2,2,1,3,4,5*** Z=4 daemon mail a=3
I would like to change only lines that contain "daemon www" and the substring Y=.. with same number of zeros.
(The number of #,#,#,#
is unknown).
Output file should look like:
daemon www X=1 ***Y=0,0,0*** Z=4 daemon www X=1 ***Y=0,0,0,0,0,0,0*** Z=4 daemon mail a=3
Any ideas ? Thanks !
Upvotes: 3
Views: 272
Reputation: 98118
One way:
sed '/daemon www.*Y=/{:l s/\(Y=\(0,\)*\)[0-9]*/\10/;/Y=\(0,\)*0\([^,0-9]\|$\)/!bl}' input
some explanation:
if this line contains daemon www and Y= # /daemon www.*Y=/{
loop # :l
a. find Y= and zeros followed by commas # s/\(Y=\(0,\)*\)
b. find a series of digits # [0-9]*
c. replace matches in 'a' and 'b' with # /\10/g
'a' and 0
d. jump to loop if cannot match the
desired pattern: Y=0,0..,0 # /Y=\(0,\)*0
e. and the pattern in d ends with a
non-digit non-comma character or the
end of line # \([^,0-9]\|$\)/!bl
Upvotes: 4
Reputation: 45670
Try:
sed '/^daemon www.*Y/{s/[0-9]\([,*]\)/0\1/g}'
in action:
$ cat input
daemon www X=1 ***Y=1,2,2*** Z=
daemon www X=1 ***Y=1,2,2,1,3,4,5*** Z=4
daemon mail a=3
$ sed '/^daemon www.*Y/{s/[0-9]\([,*]\)/0\1/g}' input
daemon www X=1 ***Y=0,0,0*** Z=
daemon www X=1 ***Y=0,0,0,0,0,0,0*** Z=4
daemon mail a=3
Upvotes: 2
Reputation: 89639
Try this:
sed -e 's/^\(daemon www X=1 .*Y=\)[0-9]\+/\10/' -e 's/,[0-9]\+/,0/g'
Upvotes: 0
Reputation: 77185
I would use awk
. But you can disregard it if you really really have to use sed
.
awk '/daemon www.*Y=*/{for(i=1;i<=NF;i++) ($i~/Y=/)?gsub(/[0-9]/,"0",$i):$i}1' file
$ cat file
daemon www X=1 ***Y=1,2,2*** Z=
daemon www X=1 ***Y=1,2,2,1,3,4,5*** Z=4
daemon mail a=3 Y=3,45,
$ awk '/daemon www.*Y=*/{for(i=1;i<=NF;i++) ($i~/Y=/)?gsub(/[0-9]/,"0",$i):$i}1' file
daemon www X=1 ***Y=0,0,0*** Z=
daemon www X=1 ***Y=0,0,0,0,0,0,0*** Z=4
daemon mail a=3 Y=3,45,
Upvotes: 2