Repeated regex replaces SED

I have the following lines (actually there are ~ 1M of these lines):

foo|||bar
qux||boo|fzx

Please note that each line contains exactly 4 fields, but the number of characters can be more than 3.

What I want to do is replace each ||with |nil|as a result:

foo|nil|nil|bar
qux|nil|boo|fzx

How to do this with sed?

I tried this but could not:

sed 's/||/|nil/g'
+5
source share
1 answer

You need to repeat the substitution until it changes:

sed ':a; s/||/|nil|/g; ta'

However, this will not handle empty fields at the beginning or end, for this you need two more templates:

sed 's/^|/nil|/; s/|$/|nil/; :a; s/||/|nil|/g; ta'

Testing

Input:

cat << EOF > infile
foo|||bar
qux||boo|fzx
|||
EOF

Run it:

<infile sed 's/^|/nil|/; s/|$/|nil/; :a; s/||/|nil|/g; ta'

Conclusion:

foo|nil|nil|bar
qux|nil|boo|fzx
nil|nil|nil|nil

awk path

awk '{ for(i=1;i<=NF;i++) if(length($i)==0) $i="nil" } 1' FS='|' OFS='|'
+16
source

All Articles