So I have this file
a chair x 0 y
a table x 0 y
a window x 0 y
a computer x 0 y
I want to replace the 0
value with 111
value for the rows that have window
in them. So the output will look like:
a chair x 0 y
a table x 0 y
a window x 111 y
a computer x 0 y
Running sed 's/window.*0/y/' a.txt
does not give me what I want.
CodePudding user response:
sed "s/ window \(.\) 0 / window \1 111 /"
Parenthesis (which need to be escaped) "group" a match. You can refer to groups by sequential number in your replacement string, preserving the matched value.
As it is unclear what your "a" / "x"/ "y" could stand in for (are they always "a"/"x"/"y", or always a single lowercase letter, or...), I can't really give you an "optimal" sed
line. If this is to be release-quality code, you need to make sure there can be no "false positives" (i.e. if "window" can appear at some other place than the second column). You could use the grouping mechanics I showed above to match the whole line, ensuring that "window" is in the second column... which could get hairy if a column could conceivably contain spaces. As I said, not enough information.
CodePudding user response:
You can use the following GNU sed solution:
sed -i -E 's/^(\S \s window\s \S \s )0(\s)/\1111\2/' a.txt
Here,
^
- start of string(\S \s window\s \S \s )
- Group 1 (\1
): one or more non-whitespaces, one or more whitespaces,window
text, one or more whitespaces, one or more non-whitespaces and one or more whitespaces0
- a0
char(\s)
- Group 2 (\2
): a whitespace
See the online demo:
#!/bin/bash
s='a chair x 0 y
a table x 0 y
a window x 0 y
a computer x 0 y'
sed -E 's/^(\S \s window\s \S \s )0(\s)/\1111\2/' <<< "$s"
Or, you can use awk
:
awk '$2 == "window" && $4 == "0"{$4=111}1' a.txt > a.txt.tmp && mv -f a.txt.tmp a.txt
It means, if Field 2 is window
and Field 4 is 0
, replace the fourth field with 111
.
See the online demo:
#!/bin/bash
s='a chair x 0 y
a table x 0 y
a window x 0 y
a computer x 0 y'
awk '$2 == "window" && $4 == "0"{$4=111}1' <<< "$s"
Output:
a chair x 0 y
a table x 0 y
a window x 111 y
a computer x 0 y
CodePudding user response:
Using sed
$ sed '/window/I{s/0/111/}' input_file
a chair x 0 y
a table x 0 y
a window x 111 y
a computer x 0 y
CodePudding user response:
Since you specifically asked for sed
. With your shown samples please try following sed
code. Here is the Online Demo for used regex in sed
code.
sed -E '/window/s/^([^[:space:]] [[:space:]] [^[:space:]] [[:space:]] [^[:space:]] [[:space:]] )[^[:space:]] (.*)$/\1111\2/' Input_file
OR To make sure that string window
is coming in 2nd field/column then try following.
sed -E '/^[^[:space:]] [[:space:]] window[[:space:]] /s/^([^[:space:]] [[:space:]] [^[:space:]] [[:space:]] [^[:space:]] [[:space:]] )[^[:space:]] (.*)$/\1111\2/' Input_file
Output will be as follows:
a chair x 0 y
a table x 0 y
a window x 111 y
a computer x 0 y