neversaint has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I have the set of files that look like this.
~/MyDir |__ file1.txt |__ file2.txt |__ file3.txt |__ ... |__ file30.txt
What I want to do is to concatenate a subset of files from above directory:
@sel_files = ( "file2.txt", "file4.txt", "file15.txt");
into a single file called 'selected.txt'. Just like I would do it manually with bash`s cat command:
$ cat file2.txt file4.txt file15.txt > selected.txt
How can I do it with Perl? The reason why I need to do it with Perl because in reality the number of files to be concatenated is a lot and varying. I need to automate the process.

---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: cat -ing Multiple files with Perl
by davorg (Chancellor) on Dec 07, 2005 at 13:25 UTC

    Put your list of files in @ARGV and then use <>.

    #!/usr/bin/perl use strict; use warnings; @ARGV = ('file2.txt', 'file4.txt', 'file15.txt'); open SEL, '>', 'selected.txt' or die $!; while (<>) { print SEL; }
    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      To expand on that, I do something which combines files specified by a glob into another. It is called like:

      $ catfiles.pl *.txt *.html > mynewfile.txt
      And it looks like:
      #!/usr/bin/perl use strict; use warnings; local $|=1; #turn of buffering for ( map { glob $_ } @ARGV ) { open my $FH, '<', $_ or do { warn "Can't open '$_' for read, skipping: $!"; next; } while (<$FH>) { print $_ } close $FH; }

      Of course, on many systems cat *.txt *.html > mynewfile.txt works just fine, but this tool is useful because (a)I can extend it when I need to do more advanced work, and (b)Win32 doesn't have cat.

      <-radiant.matrix->
      A collection of thoughts and links from the minds of geeks
      The Code that can be seen is not the true Code
      "In any sufficiently large group of people, most are idiots" - Kaa's Law
        Actually, Windows does have a cat equivalent, even though less powerfull. It is called type. Usage:
        $type /? Displays the contents of a text file or files. TYPE [drive:][path]filename $
        And of course you can redirect and/or append to files by using '>>' or '>' respectivelly.
        too bad you never actually ran your code!
Re: cat -ing Multiple files with Perl
by psychotic (Beadle) on Dec 07, 2005 at 15:49 UTC
    Since i wrote it, i might as well post it, even if the answers were more than adequate.
    use strict; my @files = qw(file1.txt file2.txt file3.txt); my $merge = (@ARGV) ? shift : 'merged.txt'; open (BUFF, '>>', $merge) or die "Unable to open: '$merge'"; while (@files) { local $_ = shift @files; my $fileData = do { local (*ARGV, $/) = [$merge] and <> }; print BUFF $fileData; } close (BUFF);
Re: cat -ing Multiple files with Perl
by jdporter (Paladin) on Dec 08, 2005 at 02:13 UTC
    sub catalanche { system qq( cat "$_" >> "$_[1]" ) for @{$_[0]}; } catalanche( \@sel_files => 'selected.txt' );
    We're building the house of the future together.
      Dear jdporter,
      Is it possible to make your snippet above to print to STDOUT? I tried this modification in mycode.pl:
      catalanche( \@sel_files );
      and then do this with mycode.pl:
      $ perl mycode.pl > mydesired_outputfile.txt
      But it doesn't work. Hope to hear from you again.

      ---
      neversaint and everlastingly indebted.......
        Untested.
        sub catalanche { if ( @_ == 0 or $_[1] eq '-' ) # let - signify stdout as well { system qq( cat "$_" ) for @{$_[0]}; } else { system qq( cat "$_" >> "$_[1]" ) for @{$_[0]}; } }
        We're building the house of the future together.
Re: cat -ing Multiple files with Perl
by TomDLux (Vicar) on Dec 08, 2005 at 17:34 UTC

    Doing cat with perl:

    The first is simply a replacement for DOS or other systems which don't provide a cat command.

    perl -p file1 file3 file14 file47 > selected.txt

    The second lets you list the files to be selected in a file. Instead of listing them all, one by one, you cat the file into the command list for the perl command.

    perl -p `cat selection.list` > selected.txt

    If you are concatenating many files, being the restrictions of command line length, the third one uses a begin block to open the file, stuff all the names into @ARGV, replacing whatever was there before ( namely the name of the section file ), and lets the -p option output print all the files.

    perl -p -e'BEGIN{ local $/; open LIST, '<', $ARGV[0]; my @list = <LIST +>; @ARGV = @list; }' selection.list > selected.txt

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      I your case the easiest way to do is: cat file*.txt >> finalfile.txt Greetings Naltagua
Re: cat -ing Multiple files with Perl
by phaylon (Curate) on Dec 07, 2005 at 13:26 UTC
    It's just walking every file, every line and writing that out to one result file. Do you have any implementation specific problems? Otherwise there's not much to tell, I'm afraid.

    Ordinary morality is for ordinary people. -- Aleister Crowley
Re: cat -ing Multiple files with Perl
by planetscape (Chancellor) on Dec 08, 2005 at 08:41 UTC