Find and Replace in multiple fields using awk

Hi,

Say I have a record "1|22| | |". In which the third and fourth fields are <space> alone. I have to replace the <Space> with <null>.

Input:

"1|22| | |" --> "1|22|<space> |<space> |"

Expected output:

"1|22|||" --> "1|22|<null> |<null>|"

I tried:

echo "1|22| | |" | awk -F '|' -v v1=" " -v v2="" 'BEGIN{OFS="|";}{gsub(v1,v2,$3);print}' 
echo "1|22| | |" | awk -F '|' -v v1=" " -v v2="" 'BEGIN{OFS="|";} {gsub(v1,v2,$4);print}' 

The above code works fine. But is there a way in which I can pass a array of fields rather than one by one?? :frowning:

You can do a loop, and use $ to turn a field number into field contents:

for(N=1; N<=NF; N++) sub(/ /, "", $N);

...but I suspect you're overthinking this a touch -- why bother using fields at all? Do a search/replace on the line itself and you'll get it all done in one gsub:

awk '{ gsub(/[|] [|]/, "||") } 1' inputfile

---------- Post updated at 10:04 AM ---------- Previous update was at 10:01 AM ----------

Okay, that doesn't work because gsub refuses to overlap like that. But my first example still works when you set FS and OFS properly.

The regex might as well be /^ $/ for that case, to prevent it eating spaces in the middle of a string.

I just want to do on few fields alone. If othert fields have space alone, that wont be a problem...I have to do a search and replace on selective fields alone

The "3|4" is the list of fields you want to replace here. It's split() into the array F so that F[1]=3, F[2]=4, using the same separator as everything else... Then we loop over that array, for(N in F) which should do two loops with N=1 and N=2 respectively. We look up the field in F, convert it to field contents with $, and substitute on it.

I think just plain sub() should be fine here, since you don't need to do more than one substitution per token.

awk -v FS="|" -v OFS="|" 'BEGIN { split("3|4", F); } { for(N in F) sub(/^ $/, "", $(F[N])) } 1' filename
1 Like
$ echo "1|2| | |5" | awk 'BEGIN {FS=IFS=OFS="|"} {if ($3==" ") {$3=""} ; if ($4==" ") {$4=""} ; print $0}'
1|2|||5