For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > July 2004 > Multiple Parameters









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Multiple Parameters
mafioso1823@contourmediagroup.com

2004-07-28, 8:56 pm

I am trying to write a search and replace script that can accept multiple
arguments, but i want the first argument to be the filename to read, the
next one to be the string to search for, the next one to be the replacement
string, and the last one to be the name of the new file it creates with the
new changes, but i can't figure out how to seperate each argument, can some
one tell me how to do something like this. Any help is very much
appreciated.

James Edward Gray II

2004-07-28, 8:56 pm

On Jul 24, 2004, at 11:38 AM, <mafioso1823@contourmediagroup.com> wrote:

> I am trying to write a search and replace script that can accept
> multiple
> arguments, but i want the first argument to be the filename to read,
> the
> next one to be the string to search for, the next one to be the
> replacement
> string, and the last one to be the name of the new file it creates
> with the
> new changes, but i can't figure out how to seperate each argument, can
> some
> one tell me how to do something like this. Any help is very much
> appreciated.


Well, command line arguments come into the program by way of the array
@ARGV. So first we should be sure you got the right number of
arguments:

die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
unless @ARGV == 4;

Then we can use it:

my($old_file, $search, $replace, $new_file) = @ARGV;

Finally, just FYI, you can do what you describe with a one-liner:

perl -pi.bak -e 's/search/replace/g' old_file

Hope that helps.

James

Jupiterhost.Net

2004-07-28, 8:56 pm



mafioso1823@contourmediagroup.com wrote:

Hello,

> I am trying to write a search and replace script that can accept multiple
> arguments, but i want the first argument to be the filename to read, the
> next one to be the string to search for, the next one to be the replacement
> string, and the last one to be the name of the new file it creates with the
> new changes, but i can't figure out how to seperate each argument, can some
> one tell me how to do something like this. Any help is very much


VIA CLI:

../replace.pl /home/oldfile "my dog spot" "your cat wiskers" /home/newfile

then in your script the are, in the the same order :

$ARGV[0] $ARGV[1] $ARGV[2] $ARGV[3]

There are modules to assist you with command line arguments as well at
search.cpan.org (like using switches so that order doesn't matter, etc)

HTH :)

Lee.M - JupiterHost.Net

> appreciated.
>
>

mafioso1823@contourmediagroup.com

2004-07-28, 8:56 pm

Another question, so far i have this script:

#!/usr/bin/perl

use IO::File;

die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
unless @ARGV == 4;
my($old_file, $search, $replace, $new_file) = @ARGV;

$fh = new IO::File "> $new_file";
if (defined $fh) {
while(<> ){
s/$search/$replace/g;
print;
}
$fh->close;
}


But the first problem is that if i try to run the code like this:

perl script.pl old.txt , \n new.txt

it will remove all the commas but won't replace them with new line
characters it will just remove them.

Also when i try to run the script it gives me this error:

Can't open ,: No such file or directory at script.pl line 11, <> line 1.
Can't open \n: No such file or directory at script.pl line 11, <> line 1.
Can't open new.txt: No such file or directory at script.pl line 11, <> line
1.


Why am i getting these errors, and how can i fix this?


Thanks in advance.


-----Original Message-----
From: James Edward Gray II [mailto:james@grayproductions.net]
Sent: Saturday, July 24, 2004 3:13 PM
To: mafioso1823@contourmediagroup.com
Cc: beginners@perl.org
Subject: Re: Multiple Parameters


On Jul 24, 2004, at 11:38 AM, <mafioso1823@contourmediagroup.com> wrote:

> I am trying to write a search and replace script that can accept
> multiple
> arguments, but i want the first argument to be the filename to read,
> the
> next one to be the string to search for, the next one to be the
> replacement
> string, and the last one to be the name of the new file it creates
> with the
> new changes, but i can't figure out how to seperate each argument, can
> some
> one tell me how to do something like this. Any help is very much
> appreciated.


Well, command line arguments come into the program by way of the array
@ARGV. So first we should be sure you got the right number of
arguments:

die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
unless @ARGV == 4;

Then we can use it:

my($old_file, $search, $replace, $new_file) = @ARGV;

Finally, just FYI, you can do what you describe with a one-liner:

perl -pi.bak -e 's/search/replace/g' old_file

Hope that helps.

James


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>



James Edward Gray II

2004-07-28, 8:56 pm

On Jul 25, 2004, at 12:55 PM, <mafioso1823@contourmediagroup.com> wrote:

> Another question, so far i have this script:
>
> #!/usr/bin/perl


use strict;
use warnings;

The above two lines ask Perl to hold you to the laws of good
programming. In return, you'll get better error messages and warnings
about things that might not be what you intended. That's a good deal
anytime, but critical in early Perl learning.

Because it forces you to write cleaner code, it also helps us read your
code, which again, can only help you.

The biggest change these rules will hold you too is declaring your
variables before you use them. In Perl, that generally looks like
this:

my $some_scalar; # declare a scalar

my $some_scalar = 'initial value'; # declare a scalar and initialize it
with a string

You only have to change one line below to get the code to pass
"strict". Can you see which one?

> use IO::File;
>
> die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
> unless @ARGV == 4;
> my($old_file, $search, $replace, $new_file) = @ARGV;
>
> $fh = new IO::File "> $new_file";
> if (defined $fh) {
> while(<> ){


The above line isn't doing what you want. It walks through @ARGV,
opening those files, and reading from them line-by-line.

We didn't empty @ARGV with our test above, so first it will open
$old_file, which is what you want. When it finishes going through
that, it will try to open your $search pattern, as a file. As you can
see, problems start here and you get the warning messages you
mentioned.

The fix is to read from only what we intend. Instead of opening just
one file, open two, one for reading and one for writing. Then,
assuming you open the old file in $old, you just need to modify your
while loop to:

while (<$old> ) {

> s/$search/$replace/g;
> print;


You don't want to print to the screen, you want to print to the new
file. Hint: You need and $fh in the above line somewhere.

Hopefully these tips will get you going. If they don't cry help again
and I'll give more specific answers. Good luck.

James

> }
> $fh->close;
> }
>
>
> But the first problem is that if i try to run the code like this:
>
> perl script.pl old.txt , \n new.txt
>
> it will remove all the commas but won't replace them with new line
> characters it will just remove them.
>
> Also when i try to run the script it gives me this error:
>
> Can't open ,: No such file or directory at script.pl line 11, <> line
> 1.
> Can't open \n: No such file or directory at script.pl line 11, <> line
> 1.
> Can't open new.txt: No such file or directory at script.pl line 11, <>
> line
> 1.
>
>
> Why am i getting these errors, and how can i fix this?
>
>
> Thanks in advance.
>
>
> -----Original Message-----
> From: James Edward Gray II [mailto:james@grayproductions.net]
> Sent: Saturday, July 24, 2004 3:13 PM
> To: mafioso1823@contourmediagroup.com
> Cc: beginners@perl.org
> Subject: Re: Multiple Parameters
>
>
> On Jul 24, 2004, at 11:38 AM, <mafioso1823@contourmediagroup.com>
> wrote:
>
>
> Well, command line arguments come into the program by way of the array
> @ARGV. So first we should be sure you got the right number of
> arguments:
>
> die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
> unless @ARGV == 4;
>
> Then we can use it:
>
> my($old_file, $search, $replace, $new_file) = @ARGV;
>
> Finally, just FYI, you can do what you describe with a one-liner:
>
> perl -pi.bak -e 's/search/replace/g' old_file
>
> Hope that helps.
>
> James
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>


James Edward Gray II

2004-07-28, 8:56 pm

(Let's keep our discussion on the list so all can help and learn.)

On Jul 25, 2004, at 8:09 PM, <mafioso1823@contourmediagroup.com> wrote:

> OK i still can't figure this out, i understand what you explained but i
> still can't figure out why it doesn't want to write to the new file
> and also
> why it only removes the commas and doesn't replace it with the new line
> character, i modified the code a little but now when i run it it gives
> me
> this weird message:
>
>
> --------weird message--------------------
> IO::File=GLOB(0x8132fe4)


You are printing an object. See below.

> ---------new code--------------------------------------------
> #!/usr/bin/perl
>
> use IO::File;
> use strict;
> use warnings;
>
> die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
> unless @ARGV == 4;
>
> my($old_file, $search, $replace, $new_file) = @ARGV;
>
>
>
> my $open_file = new IO::File;
> my $fh = new IO::File "> $new_file";


You're not checking if this succeeds any more. What if it fails?

> if ($open_file->open("< $old_file")) {
> while (<$open_file> ){
> s/$search/$replace/g;
> print $fh;


Perl thinks you want to print $fh, not print TO $fh. We need to
clarify.

print $fh $_;

# or...

$fh->print();

> }
> $fh->close;
> $open_file->close;
> }
> ---------------------------------------------------------------


Just out of curiosity, why are we using the module for this? Don't get
me wrong, I love object oriented programming, but here the interface
seems to have bitten you a few times and you're not saving yourself any
work. Here's the mundane version:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
unless @ARGV == 4;
my($old_file, $search, $replace, $new_file) = @ARGV;

open IN, '<', $old_file or die "File error: $!";
open OUT, '>', $new_file or die "File error: $!";

while (<IN> ) {
s/$search/$replace/g;
print OUT $_;
}

close IN;
close OUT;

__END__

Hope that helps.

James

mafioso1823@contourmediagroup.com

2004-07-28, 8:56 pm

Thank you very much for your help, but i have one more question, is this the
way that regex works or is it something in my code, every time i try to run
the script to search for a comma and replace it with a new line character
(\n) it just removes the commas but doesn't replace it with a new line
character.

-----Original Message-----
From: James Edward Gray II [mailto:james@grayproductions.net]
Sent: Monday, July 26, 2004 9:22 AM
To: mafioso1823@contourmediagroup.com
Cc: Perl Beginners
Subject: Re: Multiple Parameters


(Let's keep our discussion on the list so all can help and learn.)

On Jul 25, 2004, at 8:09 PM, <mafioso1823@contourmediagroup.com> wrote:

> OK i still can't figure this out, i understand what you explained but i
> still can't figure out why it doesn't want to write to the new file
> and also
> why it only removes the commas and doesn't replace it with the new line
> character, i modified the code a little but now when i run it it gives
> me
> this weird message:
>
>
> --------weird message--------------------
> IO::File=GLOB(0x8132fe4)


You are printing an object. See below.

> ---------new code--------------------------------------------
> #!/usr/bin/perl
>
> use IO::File;
> use strict;
> use warnings;
>
> die "Usage: script OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
> unless @ARGV == 4;
>
> my($old_file, $search, $replace, $new_file) = @ARGV;
>
>
>
> my $open_file = new IO::File;
> my $fh = new IO::File "> $new_file";


You're not checking if this succeeds any more. What if it fails?

> if ($open_file->open("< $old_file")) {
> while (<$open_file> ){
> s/$search/$replace/g;
> print $fh;


Perl thinks you want to print $fh, not print TO $fh. We need to
clarify.

print $fh $_;

# or...

$fh->print();

> }
> $fh->close;
> $open_file->close;
> }
> ---------------------------------------------------------------


Just out of curiosity, why are we using the module for this? Don't get
me wrong, I love object oriented programming, but here the interface
seems to have bitten you a few times and you're not saving yourself any
work. Here's the mundane version:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 OLD_FILE, SEARCH, REPLACE, NEW_FILE\n"
unless @ARGV == 4;
my($old_file, $search, $replace, $new_file) = @ARGV;

open IN, '<', $old_file or die "File error: $!";
open OUT, '>', $new_file or die "File error: $!";

while (<IN> ) {
s/$search/$replace/g;
print OUT $_;
}

close IN;
close OUT;

__END__

Hope that helps.

James


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>



James Edward Gray II

2004-07-28, 8:56 pm

On Jul 26, 2004, at 6:29 PM, <mafioso1823@contourmediagroup.com> wrote:

> Thank you very much for your help, but i have one more question, is
> this the
> way that regex works or is it something in my code, every time i try
> to run
> the script to search for a comma and replace it with a new line
> character
> (\n) it just removes the commas but doesn't replace it with a new line
> character.


What is it replacing them with? n's?

I'm betting your shell is swallowing the \, turning \n into just n. If
that's true, you have to get a \ past the shell first. On my Unix box,
both \\n and '\n' work.

Unfortunately, that doesn't solve your problem. Because then you'll
replace ,s with a \ followed by an n. You want \n translated into a
newline character, as it is in Perl's double quoted strings.

We could search your string for a \ followed by an n and replace it
with a newline character, but that opens a another can of worms: What
if you really wanted to replace with a \ and an n?

Given that, we can eval() your string to get Perl's string behavior.
That'll do what you want in this case, but may complicate some other
cases for you, say if you're making a CSV file and want to replace with
"".

It's all tradeoffs.

Here's a simple change to eval() your string:

s/$search/qq("$replace")/eeg; # update your search to this

Hope that helps.

James

mafioso1823@contourmediagroup.com

2004-07-28, 8:56 pm


Cool it works, thanks alot for your help.


-----Original Message-----
From: James Edward Gray II [mailto:james@grayproductions.net]
Sent: Monday, July 26, 2004 9:04 PM
To: mafioso1823@contourmediagroup.com
Cc: Perl Beginners
Subject: Re: Multiple Parameters


On Jul 26, 2004, at 6:29 PM, <mafioso1823@contourmediagroup.com> wrote:

> Thank you very much for your help, but i have one more question, is
> this the
> way that regex works or is it something in my code, every time i try
> to run
> the script to search for a comma and replace it with a new line
> character
> (\n) it just removes the commas but doesn't replace it with a new line
> character.


What is it replacing them with? n's?

I'm betting your shell is swallowing the \, turning \n into just n. If
that's true, you have to get a \ past the shell first. On my Unix box,
both \\n and '\n' work.

Unfortunately, that doesn't solve your problem. Because then you'll
replace ,s with a \ followed by an n. You want \n translated into a
newline character, as it is in Perl's double quoted strings.

We could search your string for a \ followed by an n and replace it
with a newline character, but that opens a another can of worms: What
if you really wanted to replace with a \ and an n?

Given that, we can eval() your string to get Perl's string behavior.
That'll do what you want in this case, but may complicate some other
cases for you, say if you're making a CSV file and want to replace with
"".

It's all tradeoffs.

Here's a simple change to eval() your string:

s/$search/qq("$replace")/eeg; # update your search to this

Hope that helps.

James


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com