phpguru
phpguru

Reputation: 2371

How to write a dynamic string replacement in git bash?

This is on Windows 10 using the Linuxy environment provided with Git Bash.

I have this line in my target source file:

'version' => 'v1.1.023',

I have this function in my ~/.bash_profile:

function tag() {
    ....
    tagname="$1"
    cmd="s:v[0-9]\\.[0-9]\\.[0-9]+:$tagname:g;"
    perl -p -i -e "$cmd" config/app.php
    ...
}

When I run the command:

$ tag v.1.1.024

The string is not replaced, therefore the version is not updated in my code. I tried a very similar script with sed instead of perl. The file isn't getting changed. I tried the same perl replacement syntax on CentOS and it worked. Note that the double-backslash appears to be required in order for the command to work on the next line when it's run in perl. That is to say, the variable string representation of the command has a double backslash so that it becomes a literal "." in the replacement.

Any ideas?

Upvotes: 1

Views: 1882

Answers (2)

Miguel Ortiz
Miguel Ortiz

Reputation: 1482

Hi @phpguru I would follow the KISS principle.

Using sed and avoiding perl

6.3. When should I use sed?

When you need a small, fast program to modify words, lines, or blocks of lines in a textfile.

function tag() {
    tagname="$1"
    sed -i -e "s:v[0-9]\.[0-9]\.[0-9]\+:$tagname:g" test.php
}

Output in my environment:

m.ortiz.montealegre@CPX-XYR3G1DTHBU MINGW64 ~
$ cat .bash_profile
function tag() {

    tagname="$1"
    sed -i -e "s:v[0-9]\.[0-9]\.[0-9]\+:$tagname:g" test.php
}

m.ortiz.montealegre@CPX-XYR3G1DTHBU MINGW64 ~
$ cat test.php
'version' => 'v1.1.023,

m.ortiz.montealegre@CPX-XYR3G1DTHBU MINGW64 ~
$ tag v1.1.024

m.ortiz.montealegre@CPX-XYR3G1DTHBU MINGW64 ~
$ cat test.php
'version' => 'v1.1.024,

Upvotes: -1

ikegami
ikegami

Reputation: 385847

-i doesn't work on Windows builds of perl.

>perl -i -pe1 foo
Can't do inplace edit without backup.

That feature uses anonymous files, which aren't supported by Windows. That said, you're not using a Windows build of perl but a cygwin build or similar. It could be that your unix emulation environment emulates anonymous files, so that might not be the the problem.

But if it is the problem, replacing -i with -i.bak will solve it. (Feel free to follow up with rm config/app.php.bak.)


By the way, you are generating Perl code, which is fragile. (Tag names containing :, \, $ or @ will cause the code to fail.) I recommend one of the following instead:

TAGNAME="$tagname" perl -i -pe's:v[0-9]\.[0-9]\.[0-9]+:$ENV{TAGNAME}:g' config/app.php

or

perl -i -pe'
   BEGIN { $tagname = shift(@ARGV); }
   s:v[0-9]\.[0-9]\.[0-9]+:$tagname:g;
' "$tagname" config/app.php

Upvotes: 2

Related Questions