Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

From command line, make perl substitute matches only after a match of another regex

Tags:

regex

file

perl

I'm making some mass character replacements inside of comments with multiple matches per line, and this reduces to the problem mentioned in the title. Is there a simple way to do this in a perl one-liner? The simplest way I've thought of so far is to do something like

perl -pi e 's/(.*regex1.*)(regex2)/$1replacement/' filename

and simply run this until the files stop changing. It seems like there must be a better way to do a one-liner for this.

Example input (the number of columns varies across the files):

   /*
    * name     val1     val2
    * foo      2345     23
    * barbaz   34       23456
    */

Example output:

   /*
    * name.....val1.....val2
    * foo......2345.....23
    * barbaz...34.......23456
    */
like image 847
jonderry Avatar asked Nov 17 '25 03:11

jonderry


1 Answers

You could try something like this:

perl -pwe 'if (m#/\*# .. m#\*/#) { 
    s/\w\.*\K( {2,})(?=\S)/ "." x length($1) /eg; }' input.txt > output.txt

But be aware that matching comments with regexes is a tricky business. As long as the comments follow your simple style, you should be ok, but watch out for it matching other comments as well.

In this one-liner, I use the flip-flop operator to match between the open and close comment symbols. Inside, it matches any alphanumeric \w followed by optional periods, and replaces any spaces (2 or more) following it with periods. The look-ahead at the end is there to prevent it adding on periods after the last word, e.g. foo....bar.....

I opted to use ( +) to capture only spaces, but you may replace that with (\s+). Replacing tabs with periods will be much trickier, though, if you want to preserve the indentation.

ETA:

You may wish to make use of the -i option to perform in-place edit on files, which is handy when doing multiple files. The safe way is to use backups, e.g. -i.bak.

like image 188
TLP Avatar answered Nov 20 '25 07:11

TLP