views:

98

answers:

3

I would like a command line function that I can run on any file to change the include("myinc.inc"); PHP statement to include 'myfile.inc'; I have made a start by adding the following to my ~/.bashrc file:

function makestandard() {
    perl -p -i -e 's/include\("([\w\.]+)"\)/include '$1'/g' $*
}

I source ~/.bashrc; and run the command at the command line as follows:

$ makestandard myfile.php

I get myfile.php modified but instead of capturing the included file name, the included file name is corrupted to be the name of the current file. As a uninformed guess, I think the bash $1 variable is interfering with the $1 perl regexp variable.

How can I fix this?


Background info (no need to read): We have started using PHP_CodeSniffer (phpcs) to sniff PHP code and report any bad "smells". Unfortunatly, phpcs doesn't fix the non-standard code, it only reports it. Hence I would like to make a script that fixes some of the easy and common non-standard elements of our PHP code. I plan to fill my makestandard bash function with a bunch of perl pie.

Shell environment: Whatever is out-of-the-box in Ubuntu 10.04.

+3  A: 

You should escape your simple quotes an remove the last parenthesis :

perl -p -i -e "s/include\(\"([\w\.])+\"\)/include '\$1'/g" $*
Colin Hebert
I get the following error when I source my *.bashrc* file when I escape the single-quotes: `bash: /home/tom/.bashrc: line 214: unexpected EOF while looking for matching '` - But all is fine if I use double-quotes so thanks for the info.
Tom
Why was this upvoted? Bash quoting does not work that way.
daxim
@daxim, my bad it's updated
Colin Hebert
It's still wrong. By exchanging `'` for `"`, you changed the meaning of `$1` from Perl's first match variable to bash's first function argument. You should've kept the outer single quotes and concentrated on properly escaping the inner single quotes according to bash rules.
daxim
@daxim it was just a typo, the `$` was supposed to be escaped. The outter single quotes would have been really ugly in this code '"'"' for a sigle quote is kind of too much. the answer as been re-edited.
Colin Hebert
+3  A: 

It isn't the bash variable, it is the single quotes in your single quoted bash string.

Chas. Owens
aha - thanks I should have spotted this from the syntax highlighting while writing the question! Escaping the single-quotes with a backslash makes the command fail to source though.
Tom
`'$1'` becomes `'\''$1'\''`. I use the [`String::ShellQuote`](http://p3rl.org/String::ShellQuote) module.
daxim
@daxim No it doesn't. It is all inside of a shell single quotes. This means the `$1` is protected from the shell. The problem was that the protection was rescinded by closing the single quoted shell string (and reopening it immediately afterward). I say `perl -nle 'print $1 if /foo="(.*)"/'` all the time.
Chas. Owens
I don't know what you're arguing here. If one wants to shellquote `foo 'bar' quux` to be included into an outer `perl -e'…'`, it really does become `foo '\''bar'\'' quux`. This isn't readily apparent from the [bash manual](http://www.gnu.org/software/bash/manual/bashref.html#Quoting), but trivially verifiable.
daxim
@daxim Ah, I misread what you wrote. I thought you were saying there were two layers of quoting that had to be done.
Chas. Owens
Thanks everyone: I actually ended up with `perl -p -i -e 's/include\(['\''\"]([\w\.]+)['\''\"]\)/include '\''$1'\''/g' $*` which seems to work well so far.
Tom
A: 

The original Perl statement, if it had worked, would have found

include("something.php") 

and written

include 'something.php')

that is, it would have removed the opening parenthesis and replace double quotes with single .. and not changed the extension as required.

The following appears to work the way the OP intended:

function makestandard() {
    perl -p -i -e 's/include\("(\w+)\.inc"\)/include("$1.php")/g' $*
}
Martin Thomas
Thanks Martin. Yes sorry about having a incorrect ")" char in the regexp and using a incorrect extension in my question. I have edited it to focus on the main issue - i.e. how to escape single-quotes.
Tom