Executing sed from php script

51 Views Asked by At

I have the following lines in a php script:

$onecount=exec('grep -oi "STRING1" FILE1 | wc -l');
$boo=$onecount;
echo($boo);
exec("sed -i 1,20s/STRING2/$boo/ FILE2");

When I execute this program, it displays the number 27, which is the correct value for $onecount (and hence for $boo), i.e. the number of times that STRING1 occurs in FILE1. I therefore expect all instances of STRING2 in the first 20 lines of FILE2 to be replaced by "27". In fact nothing changes.

BUT:
When I change the second line above from $boo=$onecount; to, say, $boo=3; then everything works as expected: The program both displays the number 3 AND correctly changes all instances of STRING2 in FILE2 to the string '3'.

The fact that all works as expected when I set $boo=3 tells me (I think) that there is no problem with the syntax of my sed command.

Another thing that hasn't worked: I have tried replacing $onecount with things like strvalue($onecount), but the problem persists.

What am I missing?

1

There are 1 best solutions below

1
mikey On BEST ANSWER

I therefore expect all instances of STRING2 in the first 20 lines of FILE2 to be replaced by "27"

If that is the case, then you should call trim on the output of your first exec command:

$onecount = exec('grep -oi "STRING1" FILE1 | wc -l');
$boo = trim($onecount);

Otherwise there will be whitespace at the front of the string:

var_dump($boo)

-> string(8) " 27"

As you can see, there are whitespace characters at the front of this string, which it sounds like you do not want.

This is actually the reason why your script works when you manually set $boo to 3 - the whitespace at the front is causing sed to fail to run, yielding a message like this:

sed: 1: "1,20s/STRING2/": unterminated substitute in regular expression

To prevent against this issue in the event you did want to have whitespace at the beginning, is to wrap the regex in apostrophes:

exec("sed -i '1,20s/STRING2/$boo/' FILE2");

Or if you are on a mac:

exec("sed -i -e '1,20s/STRING2/$boo/' FILE2");

If we put this altogether it gives me:

<?php

    $onecount = exec('grep -oi "STRING1" FILE1 | wc -l');
    $boo = trim($onecount);

    var_dump($boo);

    exec("sed -i '1,20s/STRING2/$boo/' FILE2");

    # for mac - see: https://stackoverflow.com/a/19457213/3080207
    //exec("sed -i -e '1,20s/STRING2/$boo/' FILE2");

Which seems to match the intent if I'm to understand your original question.