LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 10-03-2007, 08:15 PM   #1
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Rep: Reputation: 32
NEED HELP IN comment lines Perl script


HEllo all


I want to write a perl script which will
comment out a domain in my named.conf file for Bind.

as a test i made a file in my home directory to perform tests on it ...

the file is /home/blackice/hello

and i wrote this script

Code:
 #!/usr/bin/perl -w 

use strict;

print " please enter the domain name: ";

my  $targetdomain = <STDIN>;

chomp $targetdomain;

my  $file = "/home/blackice/hello";

open HAN,$file || die  "error opening file: $!";

while (<HAN>) {
if ( /\n^zone "$targetdomain"
\{\n(.*)type(.*);\n(.*)file(.*);\n(.*)notify(.*);\ n(.?)\}/is) {

print "hello";

}
else
{print "not hello";
}
}
so i try to make a simple test before making commenting ....

first it take the domain name as an input and if it finds that pattern including the domain name in this file it will print hello if not it will just print not hello

and the hello file contains


Code:
zone "mydomain.com" {
type master;
file "/path/to/zone/mydomain.com";
notify yes;
}

so when i run the script i got the following

Code:
# perl pth.pl
 please enter the domain name: mydomain.com
not hellonot hellonot hellonot hellonot hellonot hello

any help will be appreciated ...


and if any one have an idea for commenting that matched strings it will a nice tip for me

thanks

Last edited by adam_blackice; 10-03-2007 at 11:51 PM.
 
Old 10-04-2007, 03:31 AM   #2
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,287

Rep: Reputation: 173Reputation: 173
Code:
#!/usr/bin/perl

sub usage  { die "usage: $0 domain file\n"; };
my $domain = shift @ARGV or usage;

$SIG{ALRM} = \&usage;
alarm 3;

while (<ARGV>) {
    alarm 0;
    print;
    if (/^zone/ && /$domain/) {
        while (<ARGV>) {
            print && last if /\}/;
            print "# $_";
        }
    }
}
Code:
billym.primadtpdev>1.pl mydomain.com 1
zone "mydomain.com" {
# type master;
# file "/path/to/zone/mydomain.com";
# notify yes;
}
zone "hisdomain.com" {
type master;
file "/path/to/zone/mydomain.com";
notify yes;
}

Last edited by bigearsbilly; 10-04-2007 at 03:33 AM.
 
Old 10-04-2007, 03:37 AM   #3
Su-Shee
Member
 
Registered: Sep 2007
Location: Berlin
Distribution: Slackware
Posts: 509

Rep: Reputation: 41
That won't work that way, because <FILEHANDLE> works per default on a line and you're trying to match over line breaks.

A line break per default means under Linux and in Perl "\n".

You're trying to match that, but \n is a special thing in regular expressions and you have to switch one or two flags.

First, read "multiline mode" and second slurp your zonefile not line by line but as one string. (Assuming you're not trying to slurp 3 Gig zone file or something like this... .

You'll have to read the INPUT_RECORD_SEPARATOR ($/) in perldoc perlvar (cut and paste example..)

Right now, your "while" works via <HAN> like this: (check $_)

LINE: zone "mydomain.com" {
LINE: type master;
LINE: file "/path/to/zone/mydomain.com";
LINE: notify yes;
LINE: }

What you want is:

zone "mydomain.com" {\n type master;\n file "/path/to/zone/mydomain.com";\n notify yes;\n }\n and being able to match the \n.

You'll end up with something like $slurp =~ s/match the newlines/add a comment in front of it/appropriate modes

If you print out $slurp into a file again, the newlines will nicely be a line break again.
 
Old 10-04-2007, 06:03 AM   #4
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,287

Rep: Reputation: 173Reputation: 173
how to slurp...
just call with a filename

Code:
#!/usr/bin/perl  -s

# local $/ = undef; # uncomment this and see the difference

$x = <ARGV>;
print $x;
 
Old 10-04-2007, 03:09 PM   #5
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Original Poster
Rep: Reputation: 32
thanks for all who replay ...

by the way am so confused

i want to know what is exactly requried from me ...

bigearsbilly : i cannot understand the code you wrote

simply i want to know if iam going in the right way or not :

any body can tell me if there is any problem of my code and in the matching characters ?

Quote:
#!/usr/bin/perl -w

use strict;

print " please enter the domain name: ";

my $targetdomain = <STDIN>;

chomp $targetdomain;

my $file = "/home/blackice/hello";

open HAN,$file || die "error opening file: $!";

while (<HAN>) {
if ( /\n^zone "$targetdomain"
\{\n(.*)type(.*);\n(.*)file(.*);\n(.*)notify(.*);\ n(.?)\}/is)
and after make that i want to comment out the line of that includes the domain name that is entered by the user .

and that steps i want to make

1.) search for a multi line string including mydomain that entered by the user

2.) comment out the whole zone that including the matching domain name , from the empty line before the zone name and then to a five lines "to comment all the zone part .
 
Old 10-04-2007, 06:18 PM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
adam_blackice, your code is attempting to match a record that contains newlines. The default record separator for perl is the newline, therefore your code can never find a match.

--- rod.

Last edited by theNbomr; 10-04-2007 at 06:19 PM.
 
Old 10-04-2007, 06:56 PM   #7
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Original Poster
Rep: Reputation: 32
tahnks for you help ..
you mean that when i leave it without separator perl will interpret it as new line record ?
and how can make a matching string that contains a new line record ?

thanks
 
Old 10-04-2007, 07:11 PM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
When you use the idiom
Code:
open HAN,$file || die  "error opening file: $!";

while (<HAN>) {
perl automatically breaks up the input from the file into records that are, by default, delimited by newlines. Your while loop is iterating over each of these records. You can solve your problem in at least two ways (typical of perl).
1. You can select a record separator that is more appropriate to your data (as bigearsbilly demonstrates in post #4).
or
2. You can test for starting, ending, and middle records iteratively (as bigearsbilly has also demonstrated in post #2).

--- rod.
 
Old 10-04-2007, 07:32 PM   #9
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Original Poster
Rep: Reputation: 32
thanks for you tip ...

here is a proper way of doing that i got it from perlmonks

Quote:
#!/usr/bin/perl -w

use strict;

print " please enter the domain name: ";

my $targetdomain = <STDIN>;

chomp $targetdomain;

my $file = "/home/blackice/hello";

open HAN,$file || die "error opening file: $!";

my $comment = 0;
my $block = 0;
while (<HAN>) {
/^zone\s+"$targetdomain"/ and $comment++;
if($comment) {
$block += () = /(\{)/g; # add the number of { matches to $block
s!^!// ! if $comment && $block;
$block -= () = /(\})/g; # substract the number of } matches
$comment = 0 unless $block;
}
print;
}
this code is printing the zones commented on the shell how can i make the comments affecting inside the file on the matching zone ?/...
 
Old 10-04-2007, 08:25 PM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
First, please put your source code in [ c o d e ] tags.

Again, there are a few ways to do it. My preference is to read the file into an array, all at once.

Code:
open HAN,$file || die "error opening file: $!";
my @fileContent = <HAN>;
close(HAN);
Then, iterate over each member of the array, modifying it as necessary...
Code:
for( my $i = 0; $i < @fileContent; $i++ ){
   if( $fileContent[$i] =~ m/stuff of interest/ ){
       $fileContent[$i] =~ s/old stuff/New Stuff/;
   }
}
Then, blort the whole modified array back out to the original, or other, file.
Code:
open HAN, ">$file";
print HAN @fileContent;
close(HAN);
There are other ways, as usual with perl. If your file is huge or your available memory is small, this might not be optimal.

--- rod.
 
Old 10-04-2007, 10:34 PM   #11
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Original Poster
Rep: Reputation: 32
last question :- and i know i annoyed all of you

^zone\s+"$targetdomain" = stuff of interest


/old stuff/New Stuff/ i used \n for old stuff and \n# for new stuff and after run the script th script only comment the second line #type master; only !
 
Old 10-04-2007, 11:18 PM   #12
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
Add the 'global' switch 'g' to the end of your regex.
Code:
s/old stuff/New Stuff/g;
Without it, a regex acts on the first-longest match, only.

--- rod.
 
Old 10-05-2007, 12:47 AM   #13
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Original Poster
Rep: Reputation: 32
i did so
Code:
    $fileContent[$i] =~  s/\n/\n#/g;
but also it comment the second line only
 
Old 10-05-2007, 08:42 AM   #14
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
My only surmise, then, is that your input contained only the single newline. Without seeing your code, it is difficult to guess where it is going wrong. If you are using the method I suggested earlier, reading the whole input file into an array, and processing it line-at-a-time (which your one line code snippet suggests you are doing), it would seem more conventional to do something like
Code:
      $fileContent[$i] =~ s/^/#/;
... matching against the start-of-record, rather than embedded newlines.

--- rod.
 
Old 10-05-2007, 04:16 PM   #15
adam_blackice
Member
 
Registered: Apr 2006
Location: /*Egypt */ //cairo
Distribution: Ubuntu 7.04 , SLED 10 , Fedora , RHEL 5
Posts: 312

Original Poster
Rep: Reputation: 32
it didnot work also

i have to add some lines so that the code could read more lines

$fileContent[$i] =~ s/^/#/g;
$fileContent[$i] =~ s/\n/\n#/g;
this makes me to comment the first line and the second line of the zone just like that ...


#zone "mydomain.com" {
#type master;

and it didnot comment the other lines is there is any way to add more lines like i added to make all the lines commented as you code does ..

and thanks so much
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl: testing for blank lines Garda Programming 4 11-16-2006 07:39 PM
Perl and drawing lines Veteq Programming 2 11-27-2004 07:16 AM
Converting a Windows Perl script to a Linux Perl script. rubbercash Programming 2 07-19-2004 10:22 AM
perl(Cwd) perl(File::Basename) perl(File::Copy) perl(strict)....What are those? Baldorg Linux - Software 1 11-09-2003 08:09 PM
Including methods from a perl script into another perl script gene_gEnie Programming 3 01-31-2002 05:03 AM


All times are GMT -5. The time now is 06:46 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration