Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

perl one liner to search for a string, then search for a different string and append a new line

by BradV (Sexton)
on Dec 20, 2012 at 11:24 UTC ( [id://1009719]=perlquestion: print w/replies, xml ) Need Help??

BradV has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm trying to write a perl one liner to search for a specific <Directory ...> entry in httpd.conf, then search for the closing </Directory> and append a CustomLog line after that. I was trying perl -lne '/Directory.*awstats/;s/<\/Directory>/$1\n"CustomLog \/usr\/local\/awstats\/access_log combinedio"/' httpd.conf but that isn't working. Does anyone have a suggestions? Thanks!

Replies are listed 'Best First'.
Re: perl one liner to search for a string, then search for a different string and append a new line
by bart (Canon) on Dec 20, 2012 at 11:52 UTC
    The cause that nothing is working is probably because you process the file line by line and the parts of the strings you are looking for are on different lines. You can slurp in the whole file by using the -0 command line switch with an octal value that does not represent an existing character, as per the docs.
Re: perl one liner to search for a string, then search for a different string and append a new line
by uncoolbob (Novice) on Dec 20, 2012 at 12:08 UTC

    It took me a while to find it, but "man perlrun" will tell you how to slurp the whole file in one go (-0777)

    The /s switch on the search+replace will treat the whole file as one string - ignoring line breaks.

    The following will work on most Perl module README files

    perl -0777 -nple 's/(SUPPORT.+AND)/$1 PATCHY/s' README

    Be careful with greedy matching - that .+ should be .+? if you want the output to be "SUPPORT AND PATCHY DOCUMENTATION". In your case it will match greedily until the last </Directory> unless you add the '?'.

Re: perl one liner to search for a string, then search for a different string and append a new line
by BradV (Sexton) on Dec 20, 2012 at 13:08 UTC
    OK, I'm a little closer. It is finding the correct Directory section, it is printing the CustomLog line, but the Directory section is not printed out. That is, in the httpd.conf file I have:
    # # This is to permit URL access to scripts/files in AWStats directory. # <Directory "/usr/local/awstats/wwwroot"> Options None AllowOverride None Order allow,deny Allow from all </Directory>
    My code is: perl -0777 -elnp 's/<Directory "\/usr\/local\/awstats.+<\/Directory>/$1\nCustomLog \/usr\/local\/awstats\/logs\/access_log comdinedio/s' httpd.conf What I get out is:
    # # This is to permit URL access to scripts/files in AWStats directory. # CustomLog /usr/local/awstats/logs/access_log combinedio ?
    Any idea how to get the matched text back? Thanks!

      You need to put capturing parentheses around the text to be matched, in order to initialise $1.

      You should also definitely follow uncoolbob’s advice and use a non-greedy quantifier.

      And your code will be much easier to read if you use different delimiters, because then you won’t have to backslash all the forward slashes (“leaning toothpick syndrome”):

      perl -0777 -elnp 's{(<Directory "/usr/local/awstats.+?</Directory>}{$1 +\nCustomLog /usr/local/awstats/logs/access_log comdinedio}s' httpd.co +nf

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: perl one liner to search for a string, then search for a different string and append a new line
by BradV (Sexton) on Dec 20, 2012 at 14:18 UTC

    Great! 99.9% there. :)

    Current code is:

    perl -0777 -elnp 's|(<Directory "/usr/local/awstats.+?</Directory>)|$1+\nCustomLog /usr/local/awstats/logs/access_log comdinedio|s' httpd.conf

    It does everything I want, except there is a line-feed followed by another line-feed and a question mark after 'combinedio.' That is:

    CustomLog ... combinedio ?

    Any ideas how to get rid of at least the question mark?

      I found the reason for the question mark. I had a typo and was using 'perl -077' instead of 'perl -0777.' All is good.

      Thanks so much for your help! :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1009719]
Approved by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (4)
As of 2024-03-29 10:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found