In the canonical How can I replace a string in a file(s)? in 3. Replace only if the string is found in a certain context, I'm trying to implement the replace of a pipe with white spaces in file with structure like this:

12/12/2000|23:16:03|Shell Sc|8332|START|TEXT|WITH|SPACES|-|[END]|[Something else]

I need it like this:

12/12/2000|23:16:03|Shell Sc|8332|START TEXT WITH SPACES -|[END]|[Something else]

The code:

echo "12/12/2000|23:16:03|Shell Sc|8332|START|TEXT|WITH|SPACES|-|[END]|[Something else]" | \
 sed 's/\(START.*\)\|/ \1/g'

Any ideas ?


The problem with your command is that even with the g flag set, a particular portion of the text to be matched can only be included in a single match. Since .* is greedy, you will only end up removing the final pipe character. Not to mention your space in the replacement text is in the wrong place.

You could do this with a repeated s command in a loop, running until it doesn't match anything. Like so:

sed -e ':looplabel' -e 's/\(START.*\)|\(.*|\[END\)/\1 \2/;t looplabel'

Or, using a shorter loop label:

sed -e ':t' -e 's/\(START.*\)|\(.*|\[END\)/\1 \2/;tt'

In this particular case, all the | you want replaced with spaces come immediately after a capital letter and immediately before a capital letter or a -. You can therefore use lookarounds:

$ perl -ple 's/(?<=[A-Z])\|(?=[A-Z-])/ /g' file
12/12/2000|23:16:03|Shell Sc|8332|START TEXT WITH SPACES -|[END]|[Something else]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.