Reputation: 41
I have a requirement in unix to replace an occurrence of word with a space. My File looks something like below. I need to replace |NA| with a space
File Format
1234|NA|NA|abcd|xyz
2345|NA|NA|NA|lmn
456|NA|abcd|xya|ggh
Expected Output
1234| | |abcd|xyz
2345| | | |lmn
456| |abcd|xya|ggh
I am using the following command but it only replaces the very first occurrence
sed 's/|NA|| |/g'
Upvotes: 4
Views: 7232
Reputation: 1517
Failed utterly trying to escape the vertical bar. Then made an attempt without having the vertical bar involved and it worked! Missed also that the replacement is only one space, now corrected. This way the field is easily expandable by adding space.
awk '{gsub(/NA/," ")}1' file
1234| | |abcd|xyz
2345| | | |lmn
456| |abcd|xya|ggh
Upvotes: 0
Reputation: 203129
Just use awk for clarity, simplicity, portability, extensibility, etc., etc.:
$ awk '{while(gsub(/\|NA\|/,"| |"));}1' file
1234| | |abcd|xyz
2345| | | |lmn
456| |abcd|xya|ggh
First time through the loop the gsub() replaces all odd-numbered occurrences of the regexp and the 2nd time through it replaces any that are left. It will work as-is with any awk on any UNIX system.
Upvotes: 2
Reputation: 113814
While the g
modifier does make "global" replacements, the replacements must be non-overlapping. When overlapping replacements are required, one must loop:
$ sed ':a; s/|NA|/| |/g; ta' file.txt
1234| | |abcd|xyz
2345| | | |lmn
456| |abcd|xya|ggh
The above was tested on GNU sed. For BSD (OSX) sed (Hat tip: Jonathan Leffler), the label a
must occur only at the end of a command string:
sed -e ':a' -e ' s/|NA|/| |/g; ta' file.txt
:a
creates a label a
.
s/|NA|/| |/g
performs the substitution that you want but only for non-overlapping instances of |NA|
.
ta
tells sed to jump to label a
if the preceding substitution command resulted in any changes to the line. In this way, the substitution command is repeated as many times as necessary to replace every occurrence of |NA|
.
Upvotes: 10