Many problems. Starting with the call to "ls | grep" :)
Let's start with the code:
First, let's get a list of files:
my @files = glob( '*.txt' );
But it would be better to check if the given name is associated with a file or directory:
my @files = grep { -f } glob( '*.txt' );
Now open these files to read them:
my @fhs = map { open my $fh, '<', $_; $fh } @files;
But we need a way to handle errors - in my opinion, the best way to add:
use autodie;
At the beginning of the script (and installing autodie, if you don't already have one). Alternatively, you can:
use Fatal qw( open );
Now, if we have this, let's get the first line (as shown in your example) from all the inputs and connect it:
my $concatenated = ''; for my $fh ( @fhs ) { my $line = <$fh>; $concatenated .= $line; }
It is beautiful and readable, but you can still reduce it by preserving (in my opinion) readability to:
my $concatenated = join '', map { scalar <$_> } @fhs;
The effect is the same - $ concatenated contains the first lines of all files.
So, the whole program will look like this:
Now, perhaps you want to combine not only the first lines, but all. In this situation, instead of the code $concatenated = ... you need something like this:
my $concatenated = ''; while (my $fh = shift @fhs) { my $line = <$fh>; if ( defined $line ) { push @fhs, $fh; $concatenated .= $line; } else { close $fh; } }