Reputation: 165
I just learned today from an old question how SED works for single lines. But now I'm trying to do the same for multiple line (php file indented) and it is not working. How should that be done?
Code:
if ( empty( $donot_dump ) ) {
return false;
replace to:
if ( empty( $donot_dump ) ) {
return true;
Filename: class-prompt.php
Since this is a large file, there are TONS of return false; and return true;. So that's why I can't just make all returns trues or vice versa.
Upvotes: 0
Views: 456
Reputation: 461
Checking for the first if statement and if it's found, replace the next line.
Regarding the substitution flags of Sed, g, replace all occurrences.
$ sed 's/test/another test/g' myfile
w flag: means write the results to a file.
$ sed 's/test/another test/2' myfile
I took these examples from this sed tutorial.
Upvotes: 0
Reputation: 7519
sed '/if ( empty( $donot_dump ) )/ { N; s/false/true/ }' data
/regex/ cmd
will execute cmd
only if the line matches the regex
{ cmds }
is a group of commandsN
command appends next line from a file to the pattern spaces/regex/replacement/
substitutes regex
for replacement
In other words, this sed
checks for your desired if
statement. If it finds it, it executes a group of commands inside { ... }
. First command N
appends the next line to the pattern space and the second command s
substitutes false
for true
.
This solution works for GNU sed
. As mentioned in SigmaPiEpsilon's answer, N
command is not necessary here, use it with care. I used it in favor of n
because it gives you options that I thought might come in handy. You can read more about this in sed
manual or in this sed
tutorial.
Upvotes: 5
Reputation: 698
A note of caution about sed
multiline N
and alternatives for people with similar problems. The multiline version of sed N command is not really necessary here. Since the text to be substituted is in the next line, the single line next (n
) command is sufficient. It may also be necessary in cases where the text to be substituted is also present in the original line. This is because the multiline N
command will pull next line into the pattern space and perform the substitution on the combined line. Single line next (n
) command only acts on the next line. This is illustrated below where N
performs incorrect substitution:
$ cat class_prompt.php
if ( empty( $donot_false_dump ) ) {
return false;
$ sed '/if ( empty( \$donot_false_dump ) ) {/{ N; s/false/true/ }' class_prompt.php
if ( empty( $donot_true_dump ) ) {
return false;
$ sed '/if ( empty( \$donot_false_dump ) ) {/{ n; s/false/true/ }' class_prompt.php
if ( empty( $donot_false_dump ) ) {
return true;
The multiline N is necessary only when the search pattern extends over multiple lines.
This can also be done in perl. Like below
$ perl -pe 'if ($p) { s/false/true/ ; $p=0 } $p++
> if /if \( empty\( \$donot_false_dump \) \) {/ ' class_prompt.php
if ( empty( $donot_false_dump ) ) {
return true;
Upvotes: 0
Reputation: 204731
It should not be done with sed. sed is for simple substitutions on individual lines, that is all. When you do anything else with it you're using constructs that became obsolete in the 1980s when awk was invented and are usually non-portable and inefficient and can't be built upon to do anything else.
Given this input file:
$ cat file
foo
if ( empty( $donot_dump ) ) {
return false;
bar
Using the currently accepted sed answer on OSX:
$ sed '/if ( empty( $donot_dump ) )/ { N; s/false/true/ }' file
sed: 1: "/if ( empty( $donot_dum ...": bad flag in substitute command: '}'
With any awk in any shell on any UNIX box:
$ awk 'f{sub(/false/,"true"); f=0} /if ( empty( $donot_dump ) )/{f=1} 1' file
foo
if ( empty( $donot_dump ) ) {
return false;
bar
but in reality that whole approach is error-prone since it's using a regexp instead of string comparison and doing a partial match instead of full match and will only work for matching across 2 lines. If you're interested in a general, robust, solution for doing this type of task then post a new question.
Upvotes: 0