I have two perl commands and I want to apply one of the commands to replace a capture group in the other command.
Command 1 converts a CamelCase string to snake_case. It works as expected:
echo 'AbcDefGhi' \
| perl -p -E 's/(?:\b|(?<=([a-z])))([A-Z][a-z] )/(defined($1) ? "_" : "") . lc($2)/eg'
Result:
abc_def_ghi
Command 2 finds the CamelCase strings that need to be replaced. It works fine, too (replacing with XXX$1YYY here):
echo ' <div id="AbcDefGhi">' \
| perl -p -E 's# <div id="([^"]*)">#<div id="XXX$1YYY">#s'
Result:
<div id="XXXAbcDefGhiYYY">
But how would I combine both commands now? I tried a lot of stuff, but can't get it to work. My best, probably very bad, attempt was to use the e modifier in command 1 and then printf "$1" and pipe that into command 2, but then I think it accessed the wrong $1 from the outside perl command.
Ideally I want to have it work something like this:
echo ' <div id="AbcDefGhi">' | perl -p -E 's# <div id="([^"]*)">#MAGIC#s'
Result:
<div id="abc_def_ghi">
Solutions with other tools are welcome too, but I would really like to improve to perl knowledge.
CodePudding user response:
So basically one one-liner is to locate the correct string, and the other to change that string. Well, you're already using the /e
modifier, so why not just insert the substitution in there?
perl -p -E 's# <div id="([^"]*)">#
qq(<div id=") .
$1 =~ s/(?:\b|(?<=([a-z])))([A-Z][a-z] )/(defined($1) ? "_" : "") . lc($2)/egr .
qq(">)#sex'
Basically we did this:
perl -pE' s# .... # s/...// # '
It's a bit of a mouthful to read, so I split it up using the /x
modifier, but you can just remove that and put it on a single line.
Note that I added the /r
modifier, because we don't want to change $1
(we can't, it's read-only), we just want the value after substitution. And that is what /r
does, perform the substitution and return the string, but leave original string unchanged.
Luckily you had also already change delimiters on s///
so we don't even need to do that.
This is what the line would look like, for copy/paste purposes:
perl -p -E 's# <div id="([^"]*)">#qq(<div id=") . $1 =~ s/(?:\b|(?<=([a-z])))([A-Z][a-z] )/(defined($1) ? "_" : "") . lc($2)/egr . qq(">)#se'
I'm sure the better way is to write a simpler command, but this is the quick way to merge your commands.