Welcome to WebmasterWorld Guest from 54.166.46.226

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

Perl: Search and Replace Strings of Text -multiple files

Search and Replace Text in Perl

   
12:19 am on Jan 17, 2009 (gmt 0)

5+ Year Member



Hey everyone,

I'm trying to replace a string of text over multiple files. I think I'm running into problems with forward slashes that happen to be in the string of text I need to replace, but it could be other things as well. Here's the command I've been trying:

perl -e "s/echo '<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http://' . $myserver . '/phpBB2/templates/NoseBleed/FlopTurnRiver.css" type="text/css" -->';/echo '<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http://' . $myserver . '/nosebleed-style.css" type="text/css" -->';/g;" -pi.bak $(find . -type f)

Any suggestions?

12:31 am on Jan 17, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



yeah. you'll have to escape forward slashes ... \/ instead of just //. also: is $mysever some magic variable you left out or is

echo '<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http://' . $myserver . '/phpBB2/templates/NoseBleed/FlopTurnRiver.css" type="text/css" -->';

the actual string in your files you want to replace?

perl would try to reaplce $myserver with the variable $myserver, which doesn't exist (apart from the slashes), so you'd be better off escaping the $, so \$ (allthough .. \$myserver would be a reference to a scalar ... too drunk to test ... would that lead to further problems? hope not!)

basically, escape every /, . and $ with a \ before it.
you might also be successfull by using \Q...\E to indicate that between those two nothing special is happening ... but I'm usually too lazy to use them and just escape what needs to be

1:24 am on Jan 17, 2009 (gmt 0)

5+ Year Member



Thanks so very much for your help, this seems like it may work. I'll give it a shot and come back to let you know.

the $myserver is a variable I'm using in the php file I'm doing the replace in.

Thanks again :)

1:33 am on Jan 17, 2009 (gmt 0)

5+ Year Member



hmmm THIS:

perl -e "s/echo '<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http:\/\/' \. \$myserver \. '\/phpBB2\/templates\/NoseBleed\/FlopTurnRiver\.css" type="text\/css" -->';/echo '<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http:\/\/' \. \$myserver \. '\/nosebleed-style\.css" type="text\/css" -->';/g;" $(find . -type f)

PRODUCED THIS:

Backslash found where operator expected at -e line 1, near "s/echo '<--desktop-setup=horizontal,reverse link rel=stylesheet href=http:// \"
Backslash found where operator expected at -e line 1, near "$myserver \"
(Missing operator before \?)
Bareword found where operator expected at -e line 1, near "/phpBB2/templates"
(Missing operator before templates?)
Backslash found where operator expected at -e line 1, near "// \"
(Missing operator before \?)
Backslash found where operator expected at -e line 1, near "$myserver \"
(Missing operator before \?)
syntax error at -e line 1, near "s/echo '<--desktop-setup=horizontal,reverse link rel=stylesheet href=http:// \"
Can't find string terminator "'" anywhere before EOF at -e line 1.

1:42 am on Jan 17, 2009 (gmt 0)

5+ Year Member



Does that command line script work? It looks odd, not like correct perl syntax.

What is this at the end?

$(find . -type f)

I think the -pi.bak needs to be at the beginning with -e:

perl -pi.bak -e "your code here" input_list

Are you running that on Windows? The double-quotes around the code is Windows specific, otherwise you would use single-quotes.

I'm not sure if you are trying to use concatenation inside the regexp, that will also not work. The dot '.' is a wild card match, not the concatenation operator.

EDIT:

OK, I see it does not work, we were posting at near the same time, your post with all the errors was not there when I first reviewed the thread.

1:54 am on Jan 17, 2009 (gmt 0)

5+ Year Member



ok.

to clarify, I'm using the linux terminal to run the command.

Any suggestions?

3:23 am on Jan 17, 2009 (gmt 0)

5+ Year Member



First suggestion is read my post.
3:27 am on Jan 17, 2009 (gmt 0)

5+ Year Member



Hey krugs,

I did read it but I don't think I understand?

Sorry, I didn't mean to be rude

6:50 am on Jan 17, 2009 (gmt 0)

5+ Year Member



To quote myself:


Are you running that on Windows? The double-quotes around the code is Windows specific, otherwise you would use single-quotes.
7:14 am on Jan 17, 2009 (gmt 0)

5+ Year Member



My second suggestion would be to ask if you really need all that stuff in the regexp? Can you search for a simpler pattern?

You can try this, but I am not sure if the linux stuff on the end will work:


perl -w -pi.bak -e 's{\Qecho \'<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http://\' . $myserver . \'/phpBB2/templates/NoseBleed/FlopTurnRiver.css" type="text/css" -->\';\E}{echo \'<--desktop-setup=horizontal,reverse link rel="stylesheet" href="http://\' . \$myserver . \'/nosebleed-style.css" type="text/css" -->\';}g' $(find . -type f)

The -w switch will report any warnings when you try and run the code.

If you can explain better what you are trying to do with $(find . -type f) I can probably write it all in perl. I assume that means to find all files in the current directory that are normal files. If that is correct it may be too broad a search unless you are sure you need to edit all the files in the current directory.

8:49 am on Jan 17, 2009 (gmt 0)

10+ Year Member



The majority of your search term is not changing so I've removed all of the static content to produce

find . -type f -print0 xargs -0 perl -w -pi.bak -e 's/phpBB2.*FlopTurnRiver\.css/nosebleed-style.css/g;'

(solid pipe character before xargs)

5:49 pm on Jan 17, 2009 (gmt 0)

5+ Year Member



I'd recommend the regexp be slightly modified to make the matching non-greedy (.*?):

's/phpBB2.*?FlopTurnRiver\.css/nosebleed-style.css/g;'

Otherwise it could match way more than necessary if the same pattern repeats later in the string/line.