in reply to Read from multiple files change the data with a script and the write the respective output files with a different extension

I have tried a few methods unsuccessfully
You should have shown us those attempts, so we could help you understand why they failed, and how to improve them.

Anyway, a rather simple and straightforward solution to your problem, is to turn your code into a function:

sub process_file { my ($original, $final) = @_; open( my $original_fh, "<", $original ) or die $!; open( my $final_fh, ">", $final ) or die $!; my $first = <$original_fh>; print $final_fh $first; my @replace = $first =~ /"([^"]*)"/g; while (my $line = <$original_fh>) { print "Enter the desired number of columns: "; my $nr = <STDIN>; chomp($nr); $line =~ s/((\w\w\t){$nr})/$1\n/g; $line =~ s/\t/,/g; $line =~ s/(\d{2})/$replace[$1]/g; print $final_fh $line; } close $original_fh; close $final_fh; }
And call that function on all your files (process_file("A.txt", "B.csv");).

You can get the list of files using glob ; this will return the list of files that match a given pattern: my @files = glob 'path/*.txt'; If you don't provide a path, glob will look into the current directory, which you can change with chdir.

And to change the extension, you can just use a substitution: my $new_file = $name =~ s/txt$/csv/r;

Edit: changed the last sentence, Akatsuki obviously already knows about substitutions.

  • Comment on Re: Read from multiple files change the data with a script and the write the respective output files with a different extension
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Read from multiple files change the data with a script and the write the respective output files with a different extension
by Akatsuki (Novice) on Oct 13, 2016 at 11:27 UTC

    Thank you very much for your help, but after I turn my code into a function, I still can't figure out how to read all the files and replace the extension...I wrote something like this:

    #!/usr/bin/perl use warnings; use strict; sub process_file { my ($original, $final) = @_; open( my $original_fh, "<", $original ) or die $!; open( my $final_fh, ">", $final ) or die $!; my $first = <$original_fh>; print $final_fh $first; my @replace = $first =~ /"([^"]*)"/g; while (my $line = <$original_fh>) { print "Enter the desired number of columns: "; my $nr = <STDIN>; chomp($nr); $line =~ s/((\w\w\t){$nr})/$1\n/g; $line =~ s/\t/,/g; $line =~ s/(\d{2})/$replace[$1]/g; print $final_fh $line; } close $original_fh; close $final_fh; } my @files = glob '*.txt'; my $new_file = $name =~ s/txt$/csv/r; process_file($files, $new_file);

    but I know it can't run...I didn't quite understand how can I use the substitution that you wrote because I know that $name is not declared. I appreciate any advice you can give me!

      You have many files and want to process one at a time, so use a loop:

      my @files = glob '*.txt'; for my $name (@files) { my $new_file = $name =~ s/txt$/csv/r; process_file($name, $new_file); }

        If you could help me with another problem I encountered in this program I would be very grateful. I want to enter the number of columns, only once for all the files, not for every file. My original code is:

        while (my $line = <$original_fh>) { print "Enter the desired number of columns: "; my $nr = <STDIN>; chomp($nr); $line =~ s/((\w\w\t){$nr})/$1\n/g; $line =~ s/\t/,/g; $line =~ s/(\d{2})/$replace[$1]/g; print $final_fh $line; }

        and I tried something like this unsuccessfully

        while (my $line = <$original_fh>) { for my $file (@files) { print "Enter the desired number of columns: "; my $nr = <STDIN>; chomp($nr); $line =~ s/((\w\w\t){$nr})/$1\n/g; } $line =~ s/\t/,/g; $line =~ s/(\d{2})/$replace[$1]/g; print $final_fh $line; }

        Thank you very much for your help. It's all clear now.