Something like:
sed '/^[[:blank:]]*B$/{n;s/Hello/Hi/g;}'
That assumes there are no consecutive B
s (one B
line followed by another B
line).
Otherwise, you could do:
awk 'last ~ /^[[:blank:]]*B$/ {gsub("Hello", "Hi")}; {print; last=$0}'
The sed
equivalent would be:
sed 'x;/^[[:blank:]]*B$/{
g;s/Hello/Hi/;b
}
g'
To replace the second word after B
, or to replace world
with universe
only if two lines above contained B
:
awk 'l2 ~ /B/ {gsub("world","universe")}; {print; l2=l1; l1=$0}'
To generalise it to n
lines above:
awk -v n=12 'l[NR%n] ~ /B/ {gsub("foo", "bar")}; {print; l[NR%n]=$0}'
You need to set the field separator (FS
) properly. By default, awk
uses any horizontal whitespace(s) as the field separator, so in your case SAMS
becomes one field and CLUB
becomes another. Hence, {gsub("SAMS CLUB","SAM\'S CLUB",$3);print}
is not working expectedly.
You can do:
awk -F ', +' '{gsub("SAMS CLUB","SAM'\''S CLUB",$3); print}' OFS=", " file.txt
-F ', +'
sets FS
as comma, followed by one or more space(s). If you are unsure about the spaces, use character class [:blank:]
instead to represent any horizontal whitespace and change OFS
to meet your need as well.
Example:
% cat file.txt
column1, coluumn2, coulumn3, column4, column5
1, item1, WALMART, 2.39, 50
2, item2, TARGET, 4.99, 52
3, item3, SAMS CLUB, 8.19, 15
4, item4, KROGER, 12.49, 33
5, item6, WEGMANS, 32.69, 75
6, item6, TARGET, 12.99, 25
7, item7, SAMS CLUB, 8.19, 92
% awk -F ',[[:blank:]]+' '{gsub("SAMS CLUB","SAM'\''S CLUB",$3); print}' OFS=", " file.txt
column1, coluumn2, coulumn3, column4, column5
1, item1, WALMART, 2.39, 50
2, item2, TARGET, 4.99, 52
3, item3, SAM'S CLUB, 8.19, 15
4, item4, KROGER, 12.49, 33
5, item6, WEGMANS, 32.69, 75
6, item6, TARGET, 12.99, 25
7, item7, SAM'S CLUB, 8.19, 92
Best Answer
Something along these lines should do it:
And equivalently and more terse (from the comments):