Problem: perl negative look-ahead assertion in multi-line mode

C

cibalo

Hello,
I have updated/modified my mysql database in my free website recently.
I have to re-code all my php files such that an extra statement has to
be inserted before the last mysql_query call. It may have more than
one mysql_query call in some of my php files.

I try to use a negative look-ahead assertion to make such a change as
follows.

I would like to insert just one "new_insert" line before the "coding
line 4". And my php file looks like this.

$ echo -e "coding line 1 test 1\ncoding line 2 mysql_query 2\ncoding
line 3 test 3\ncoding line 4 mysql_query 4\ncoding line 5 test 5"
coding line 1 test 1
coding line 2 mysql_query 2
coding line 3 test 3
coding line 4 mysql_query 4
coding line 5 test 5

Then I perl-regex with negative look-ahead assertion in multi-line
mode (/smg or /sg or /mg) like this:

$ echo -e "coding line 1 test 1\ncoding line 2 mysql_query 2\ncoding
line 3 test 3\ncoding line 4 mysql_query 4\ncoding line 5 test 5" |
perl -pe '/mysql_query(?!.*mysql_query)/smg && print "new_insert\n"'
coding line 1 test 1
new_insert
coding line 2 mysql_query 2
coding line 3 test 3
new_insert
coding line 4 mysql_query 4
coding line 5 test 5

However, my "coding line 2" gets changed too. And that is not what I'm
looking for.

Or, perl negative look-ahead assertion doesn't like me! Can you please
let me know what I'm missing?

Thank you very much in advance!!!

Best Regards,
cibalo
 
C

Charles DeRykus

Hello,
I have updated/modified my mysql database in my free website recently.
I have to re-code all my php files such that an extra statement has to
be inserted before the last mysql_query call. It may have more than
one mysql_query call in some of my php files.

I try to use a negative look-ahead assertion to make such a change as
follows.

I would like to insert just one "new_insert" line before the "coding
line 4". And my php file looks like this.

$ echo -e "coding line 1 test 1\ncoding line 2 mysql_query 2\ncoding
line 3 test 3\ncoding line 4 mysql_query 4\ncoding line 5 test 5"
coding line 1 test 1
coding line 2 mysql_query 2
coding line 3 test 3
coding line 4 mysql_query 4
coding line 5 test 5

Then I perl-regex with negative look-ahead assertion in multi-line
mode (/smg or /sg or /mg) like this:

$ echo -e "coding line 1 test 1\ncoding line 2 mysql_query 2\ncoding
line 3 test 3\ncoding line 4 mysql_query 4\ncoding line 5 test 5" |
perl -pe '/mysql_query(?!.*mysql_query)/smg && print "new_insert\n"'
coding line 1 test 1
new_insert
coding line 2 mysql_query 2
coding line 3 test 3
new_insert
coding line 4 mysql_query 4
coding line 5 test 5

However, my "coding line 2" gets changed too. And that is not what I'm
looking for.

Or, perl negative look-ahead assertion doesn't like me! Can you please
let me know what I'm missing?

Since you want to insert just before the last mysql_query line, you can
use .* greediness to avoid a negative look-ahead:

echo ... |
perl -0777 -pe 's/ (.*) (coding .*? query .*? \n)/$1new_insert\n$2/sx'
 
R

Rainer Weikusat

cibalo said:
I have updated/modified my mysql database in my free website recently.
I have to re-code all my php files such that an extra statement has to
be inserted before the last mysql_query call. It may have more than
one mysql_query call in some of my php files.

I try to use a negative look-ahead assertion to make such a change as
follows.

I would like to insert just one "new_insert" line before the "coding
line 4". And my php file looks like this.

$ echo -e "coding line 1 test 1\ncoding line 2 mysql_query 2\ncoding
line 3 test 3\ncoding line 4 mysql_query 4\ncoding line 5 test 5"
coding line 1 test 1
coding line 2 mysql_query 2
coding line 3 test 3
coding line 4 mysql_query 4
coding line 5 test 5

Strictly, this isn't related to the shell and not related to Perl, but
if you want to make a modification to a set of text files, have you
considered using a text editor?

NB: The 'compound command' below was executed in a directory which
contained three copies of the 'demo file' whose content was included in
the original posting.

for x in *; do
ed "$x" <<'TT'
$
?mysql_query?i
new_insert
..
wq
TT
done

This invokes ed on every file in the current directory, with 'command
input' coming from a here document (separator quoted to prevent 'shell
expansion' of the text). The ed commands are

$

Go to the last line of the input file.

?mysql_query?i

Search backwards (regexp) for the first msql_query and insert text in
front of that line.

new_insert

The text to insert.

..

'Exit insert-mode' command.

wq

Write changes and quit (non-standard, BSD-originated command).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top