Search code examples
regexperlawksedquotes

Replace spaces differently depending on outside or inside single quotes


I have input which has some fields

  • separated by spaces,
  • some other are enclosed in quotes and also seperated by spaces

Here is an example input:

active=1 'oldest active'=0s disabled=0 'function call'=0

I would like to replace :

  • all spaces outside quotes by | and
  • all inside quotes by _

Output would be:

active=1|'oldest_active'=0s|disabled=0|'function_call'=0

I tried different solutions with sed or perl found on the web but did not managed to do want I want.


Solution

  • $ s="active=1 'oldest active'=0s disabled=0 'function call'=0"
    $ echo "$s" | perl -pe "s/'[^']*'(*SKIP)(*F)| /|/g; s/ /_/g"
    active=1|'oldest_active'=0s|disabled=0|'function_call'=0
    

    Two step replacement:

    • First, '[^']*'(*SKIP)(*F) will skip all patterns surrounded by ' and replace the remaining spaces with |
    • Second, the spaces now left inside ' will be replaced with _


    Alternate solution:

    $ echo "$s" | perl -pe "s/'[^']*'/$& =~ s| |_|gr/ge; s/ /|/g"
    active=1|'oldest_active'=0s|disabled=0|'function_call'=0
    
    • Inspired from this answer
    • '[^']*'/$& =~ s| |_|gr/ge replace all spaces in matched pattern '[^']*' using another substitute command. The e modifier allows using command instead of string in replacement section
    • the remaining spaces are then taken care with s/ /|/g


    Further reading: