Andrew
Andrew

Reputation: 45

How to make a script for two txt files with different names in perl

I want to make the same calculations in two similar files, but I do not want to double the code for each file nor to create two scripts for this.

my $file = "file1.txt";
my $tempfile = "file1_temp.txt";
if (not defined $file) {
    die "Input file not found";
}

open(my $inputFileHandler, '<:encoding(UTF-8)', $file)
  or die "Could not open file '$file' $!";
  
open(my $outs, '>', $tempfile) or die $!;

/*Calculations made*/

close($outs);
copy($tempfile,$file) or die "Copy failed: $!";
unlink($tempfile) or die "Could not delete the file!\n";
close($inputFileHandler);

So i want to do the exact calculations for file2.txt_temp and copy it in file2.txt is there a way to do it without writing the code again for file2?

Thank you very much.

Upvotes: 2

Views: 59

Answers (3)

TLP
TLP

Reputation: 67910

There is a certain Perl feature that is designed especially for cases like this, and that is this:

$ perl -pi -e'/*Calculations made*/' file1.txt file2.txt ... fileN.txt

Loosely referred to as "in-place edit", which basically does what your code does: It writes to a temp file and then overwrites the original.

Which will apply your calculations to the files named as arguments. If you have complex calculations you can put them in a file and skip the -e'....' part

$ perl -pi foo.pl file1.txt ...

Say for example that your "calculations" consist of incrementing each pair of numbers by 1:

s/(\d+) (\d+)/($1 + 1) . ($2 + 1)/ge

You would do either

$ perl -pi -e's/(\d+) (\d+)/($1 + 1) . ($2 + 1)/ge' file1.txt file2.txt
$ perl -pi foo.pl file1.txt file2.txt

Where foo.pl contains the code.

Be aware that the -i switch is destructive, so make backups before running the command. You can supply a backup extension to save a backup, but that backup is overwritten if you run the command again. E.g. -i.bak.

  • -p places a while (<>) loop around your code, followed by a print of each line,
  • -i.bak does the editing of the original file, and saves a backup with the extension, if it is supplied.

Upvotes: 1

Georg Mavridis
Georg Mavridis

Reputation: 2341

Assuming your code is well written (not manipulating any globals, ...) you could use a for-loop

foreach my $prefix ('file1', 'file2') {
    my $file = $prefix . ".txt";
    my $tempfile = $prefix . "_temp.txt";
    ...
}

Upvotes: 1

Dave Cross
Dave Cross

Reputation: 69314

Write your code as a Unix filter. Read the data from STDIN and write it to STDOUT. Your code will be simpler and your program will be more flexible.

#!/usr/bin/perl

use strict;
use warnings;

while (<STDIN>) {
  # do a calculation using the data that is in $_
  print $output_data
}

The cleverness is in how you call the program:

$ ./my_clever_filter < file1.txt > file1_out.txt
$ ./my_clever_filter < file2.txt > file2_out.txt

See The Unix Filter Model: What, Why and How? for far more information.

Upvotes: 4

Related Questions