Is sed the right tool for this job?
I think sed
is a fine tool for the job you are trying to do. The pattern you tried was close, but had a few things wrong with it:
- The option swith,
-e
, and
- Your substitution command's search/replace pattern.
Which option switch should I use?
Instead of sed -e
, which outputs its results to stdout
but leaves your file unchanged, you want to use sed -i
, to edit the file "in-place", saving the changes it made back to the file. From sed's man page regarding the -i
switch:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
What about my substitution command's search/replace pattern?
For the substitution command you send to sed, you want to match strings that begin with $variable
and then end with anything else. The search pattern I would use for that is:
\$\(variable\w\+\)
A few points about that:
- (We need to escape
$
with a \
because by itself $
has a special meaning (end of line))
\w
is the regular expression pattern that matches any word-like character as well as _
\+
means "one or more of the previous pattern"
- Anything inside escaped parentheses, e.g.
\(...\)
gets put into a group for either alternating patterns or to be "remembered" for replacement. In our case, we're using them to remember them for replacement.
All together, it basically means, "find strings that begin with $variable
and then end with anything else, and remember what you found (minus the dollar sign, since it's not inside the parentheses)."
Next, we need to specify the replacement pattern. Since we have a pattern for what we want to find, we just need to specify what to replace it with:
'\1'
The \1
stands for "the first back-reference", where back-reference is the fancy term for "stuff that matches the first pattern we want to remember (what we put inside the \(\)
).
Also note:
- You can have multiple groups of
\(\)
in your search pattern; the second would be \2
, the third would be \3
, etc.
\0
is a special back-reference which contains the entire string that matched the search pattern. (In our case, it would also contain the $
's we want to remove.)
Also, we want to replace every occurrence of the search pattern that we find, not just on a single line in the file. That is specified with the g
flag, which stands for "global".
The substitution command, s
, the search pattern, the replacement pattern, and the global flag, are all separated by the slash character, /
.
That's it for the substitution command. After that, you pass the name of the file or a shell file pattern as the third argument to sed. Putting this all together, we get:
sed -i "s/\$\(variable\w\+\)/'\1'/g" myscript.php
I threw together my own little version of myscript.php
to test and verify that the regex I crafted would do what you need. For your reference, I've included before and after versions:
Before:
<?php
lorem ipsum $variable_like_that
foo bar $variable_like_other baz
one two three $variable_this_thing four
$variable_like_this five six seven eight
?>
After:
<?php
lorem ipsum 'variable_like_that'
foo bar 'variable_like_other' baz
one two three 'variable_this_thing' four
'variable_like_this' five six seven eight
?>
For more information, you can also read more here: Sed - An Introduction and Tutorial by Bruce Barnett.
Hope this helps!