Skip to main content
Integrated Stephanes comment.
Source Link
Uwe
  • 3.4k
  • 20
  • 20
perl -pe 's/(".*?")/do{$a = $1;$&; $a =~ s: +:,:g; $a}/ge;'

Essentially, this is just a global regex replacement s/regex/replacement/g. The regex is ".*?", it matches every substring that starts with " and ends with the next following ". The tricky parts are:

  • The replacement is not a string, but an expression that is evaluated. (That's the meaning of the e modifier after g.)
  • The expression that is evaluated is again a global regex replacement s:regex:replacement:g that replaces any non-empty sequence of spaces by a comma. (We cannot use the same delimiter as in the outer replacement, so we use : instead of /.)
  • In order to execute the inner regex replacement, we have to assign the matched substring of the outer replacement $1$& to some other variable $a, then perform the inner replacement on $a, and finally print $a.

With a sufficiently recent perl version, the assignment to an auxiliary variable can be avoided. Using the r modifier, the inner replacement can be performed directly on a copy of the matched substring $& (thanks to Stéphane Chazelas):

perl -pe 's/".*?"/$&=~s: +:,:gr/ge;'
perl -pe 's/(".*?")/do{$a = $1; $a =~ s: +:,:g; $a}/ge;'

Essentially, this is just a global regex replacement s/regex/replacement/g. The regex is ".*?", it matches every substring that starts with " and ends with the next following ". The tricky parts are:

  • The replacement is not a string, but an expression that is evaluated. (That's the meaning of the e modifier after g.)
  • The expression that is evaluated is again a global regex replacement s:regex:replacement:g that replaces any non-empty sequence of spaces by a comma. (We cannot use the same delimiter as in the outer replacement, so we use : instead of /.)
  • In order to execute the inner regex replacement, we have to assign the matched substring of the outer replacement $1 to some other variable $a, then perform the inner replacement on $a, and finally print $a.
perl -pe 's/".*?"/do{$a = $&; $a =~ s: +:,:g; $a}/ge;'

Essentially, this is just a global regex replacement s/regex/replacement/g. The regex is ".*?", it matches every substring that starts with " and ends with the next following ". The tricky parts are:

  • The replacement is not a string, but an expression that is evaluated. (That's the meaning of the e modifier after g.)
  • The expression that is evaluated is again a global regex replacement s:regex:replacement:g that replaces any non-empty sequence of spaces by a comma. (We cannot use the same delimiter as in the outer replacement, so we use : instead of /.)
  • In order to execute the inner regex replacement, we have to assign the matched substring of the outer replacement $& to some other variable $a, then perform the inner replacement on $a, and finally print $a.

With a sufficiently recent perl version, the assignment to an auxiliary variable can be avoided. Using the r modifier, the inner replacement can be performed directly on a copy of the matched substring $& (thanks to Stéphane Chazelas):

perl -pe 's/".*?"/$&=~s: +:,:gr/ge;'
Source Link
Uwe
  • 3.4k
  • 20
  • 20

perl -pe 's/(".*?")/do{$a = $1; $a =~ s: +:,:g; $a}/ge;'

Essentially, this is just a global regex replacement s/regex/replacement/g. The regex is ".*?", it matches every substring that starts with " and ends with the next following ". The tricky parts are:

  • The replacement is not a string, but an expression that is evaluated. (That's the meaning of the e modifier after g.)
  • The expression that is evaluated is again a global regex replacement s:regex:replacement:g that replaces any non-empty sequence of spaces by a comma. (We cannot use the same delimiter as in the outer replacement, so we use : instead of /.)
  • In order to execute the inner regex replacement, we have to assign the matched substring of the outer replacement $1 to some other variable $a, then perform the inner replacement on $a, and finally print $a.