user1440061
user1440061

Reputation: 445

Perl reading and writing in files

Alright, so I'm back with another question. I know in Python there is a way to read in a file without specifying which file it will be, until you are in the command prompt. So basically you can set the script up so that you can read in any file you want and don't have to go back and change the coding every time. Is there a way to do this in Perl? If so, can you write files like that too? Thanks.

This is what I have:

open (LOGFILE, "UNSUCCESSFULOUTPUT.txt") or die "Can't find file";       
open FILE, ">", "output.txt" or die $!;

while(<LOGFILE>){
print FILE "ERROR in line $.\n" if (/Error/);
}






close FILE;
close LOGFILE;                  

This is what I have nome:

#!/usr/local/bin/perl


my $argument1 = $ARGV[0];
open (LOGFILE, "<$argument1") or die "Can't find file";     

open FILE, ">>output.txt" or die $!;


while(<LOGFILE>){
print FILE "ERROR in line $.\n" if (/Error/);
}





close FILE;
close LOGFILE;

And it's still not appending...

Upvotes: 2

Views: 1854

Answers (3)

PinkElephantsOnParade
PinkElephantsOnParade

Reputation: 6592

This is what I believe you want:

#!usr/bin/perl
my $argument1 = $ARGV[0];

open (LOGFILE, "<$argument1") or die "Can't find file";       
open (FILE, ">output.txt") or die $!;

while(<LOGFILE>){
print FILE "ERROR in line $.\n" if (/Error/);
}

close FILE;
close LOGFILE; 

Ran as from the command line:

> perl nameofpl.pl mytxt.txt

For appending change this line:

 open (FILE, ">output.txt") or die $!;

To the remarkably similar:

 open (FILE, ">>output.txt") or die $!;

Upvotes: 2

TLP
TLP

Reputation: 67910

I assume you are asking how to pass an argument to a perl script. This is done with the @ARGV variable.

use strict;
use warnings;

my $file = shift;   # implicitly shifts from @ARGV
print "The file is: $file\n";

You can also make use of the magic of the diamond operator <>, which will open the arguments to the script as files, or use STDIN if no arguments are supplied. The diamond operator is used as a normal file handle, typically while (<>) ...

ETA:

With the code you supplied, you can make it more flexible by doing this:

use strict;
use warnings;  # always use these
my $file    = shift;                 # first argument, required
my $outfile = shift // "output.txt"; # second argument, optional

open my $log, "<", $file    or die $!;
open my $out, ">", $outfile or die $!;

while (<$log>) {
    print $out "ERROR in line $.\n" if (/Error/);
}

Also see ikegami's answer on how to make it more like other unix tools, e.g. accept STDIN or file arguments, and print to STDOUT.

As I commented in your earlier question, you may simply wish to use an already existing tool for the job:

grep -n Error input.txt > output.txt

Upvotes: 2

ikegami
ikegami

Reputation: 386551

Command line arguments are provided in @ARGV. You can do as you please with them, including passing them as file names to open.

my ($in_qfn, $out_qfn) = @ARGV;
open(my $in_fh,  '<', $in_qfn ) or die $!;
open(my $out_fh, '>', $out_qfn) or die $!;
print $out_fh $_ while <$in_fh>;

But that's not a very unixy way of doing things. In unix tradition, the following will read from every file specified on the command line, one line at a time:

while (<>) {
    ...
}

Output is usually placed in files through redirection.

#!/usr/bin/env perl
# This is mycat.pl
print while <>;

# Example usage.
mycat.pl foo bar > baz

# Edit foo in-place.
perl -i mycat.pl foo

The only time one usually touches @ARGV is to process options, and even then, one usually uses Getopt::Long instead of touching @ARGV directly.


Regarding your code, your script should be:

#!/usr/bin/env perl
while (<>) {
   print "ERROR in line $.\n" if /Error/;
}

Usage:

perl script.pl UNSUCCESSFULOUTPUT.txt >output.txt

You can get rid of perl from the command if you make script.pl executable (chmod u+x script.pl).

Upvotes: 3

Related Questions