Reputation: 53
My goal is to replace all named constants in a *.bas
file with their corresponding values, then append a comment to the line with the value-constant pair for future reference.
For example, I want to change this line:
Print #lngFile, rst.GetString(adClipString, -1, ",", vbNullString);
To this:
Print #lngFile, rst.GetString(2, -1, ",", vbNullStrings); '2=adClipString
Where the ADODB constant adClipString
is replaced with its long value 2
, and a comment is appended to the line.
The closest I've gotten is the following:
perl -pi -e 's/adClipString(.+\n)/2$1\x272=adClipString\n/' -- somefile.bas
...but I can't figure out how to exclude the \n
from the capturing group without also overwriting every line in the file. As written, the comment is placed on a new line (which is not what I want). I'm sure the answer is right in front of me.
I'm new to perl, having only run it on the command line. I'm sure there is a better [read: working] way to approach this.
Upvotes: 2
Views: 216
Reputation: 107889
.
doesn't match newlines, and perl -p
processes one line at a time, so the string to replace never contains more than one line, and you don't need to match the newline character at all.
perl -pi -e 's/\badClipString\b(.*)/2$1\x272=adClipString/' -- somefile.bas
I changed .+
to .*
because you didn't give any indication that adClipString
shouldn't be matched at the end of a line. I also surrounded the word to replace with \b
so that things like thisIsABadClipStringOtherVariable
won't get replaced.
The added complication is that you have a file with Windows line endings: CR+LF. .
doesn't match LF (line feed, the Unix/POSIX/basically-everyone-but-Windows-nowadays newline character) but it does match CR (carriage return). So this replacement puts a CR in the middle of the line (just before the comment start), which may confuse Windows programs. One way to fix this is to exclude the CR from the “rest of line” group.
perl -pi -e 's/\badClipString\b([^\r\n]*)/2$1\x272=adClipString/' -- somefile.bas
Another way to do this transformation would be to treat the string replacement and adding a comment as separate operations. An s
command is considered true only if it makes a replacement.
perl -pi -e 's/\badClipString\b/2/ and s/\r?$/\x272=adClipString$&/' -- somefile.bas
Or, in a less one-liner-y but more readable way:
perl -pi -e 'if (s/\badClipString\b/2/) { s/\r?$/\x272=adClipString$&/ }' -- somefile.bas
The regex \r?$
matches at the end of a line, with an optional CR. The substitution puts additional text at the end of a line, with $&
(which stands for the whole string matched by the regex) at the end to preserve the optional CR.
Upvotes: 1