I'm trying to read every text file in a directory into a variable then print the first 100 characters, including line breaks. However, Perl says that the files don't exist even though they really do exist.

use strict;
use warnings;

my $dir = "C:\\SomeFiles";
my @flist;

open(my $fh, "dir /a:-d /b $dir |") || die "$!";

while (<$fh>) {
    if ($_ =~ /.*(.txt)$/i) {
        push(@flist, $_);

foreach my $f (@flist) {
    print "$dir\\$f";
    my $txt = do {
        local $/ = undef;
        open(my $ff, "<", "$dir\\$f") || die "$!";
    print substr($txt, 0, 100);

When I run the script, the following is written to the console:

No such file or directory at script.pl line 19, <$fh> chunk 10.

It's looking at the right file and I'm certain that the file exists. When I try using this method to open a single file rather than getting each file via an array with foreach, it works just fine. Is there something obvious that I've overlooked here?

  • Beware of hidden whitespace: use chomp – ThisSuitIsBlackNot Dec 19 '13 at 22:56
  • Also, reading the entire file into memory in order to print just the first 100 characters is wasteful. Why not use read? – ThisSuitIsBlackNot Dec 19 '13 at 23:16
  • @ThisSuitIsBlackNot: Printing the first 100 characters is a sample task for the purpose of explaining the issue I'm having. My true task does involve the entire document and isn't relevant to the open issue. (The error occurs when trying to open the document, before trying to use it for anything.) – Alex A. Dec 19 '13 at 23:19
  • Oh, well you should have just said that! :) As for the error, that was the reason for my comment about chomp. You're not stripping the trailing end-of-line characters from your file names before you try to open them. – ThisSuitIsBlackNot Dec 19 '13 at 23:23
  • You're trying to open C:\SomeFiles\C:\SomeFiles\file1.txt. – Jim Davis Dec 20 '13 at 13:37

A better solution is to use readdir() instead (or File::Find if you ever want to do it recursively):

my $dir = "C:\\SomeFiles";

opendir(my $dh, $dir) || die "$!";

    if ($file =~ /\\.txt$/i) {
        print $file . "\n";
        my $txt = do {
            local $/ = undef;
            open(my $ff, "<", "$dir\\$file") || die "$!";
        print substr($txt, 0, 100) . "\n";

  • 8
    You should probably remove the pipe symbol from the opendir command. – TLP Dec 19 '13 at 23:14
  • Thanks for quick and helpful answer! I made a couple edits to get it to work properly. I'm not familiar with File::Find; could you please provide an example of how it would be used in this situation? – Alex A. Dec 20 '13 at 17:47
  • @TLP: thanks; good point. copy-n-paste error. – Wes Hardaker Dec 20 '13 at 22:04
  • @Alex: Basically it's much more powerful and useful if you need to look in an entire directory tree. I've linked the URL for the documentation above. You should probably look at that. It is more complex than using opendir, though, so you should use opendir unless you need to dive into subdirectories. search.cpan.org/~rjbs/perl-5.18.1/lib/File/Find.pm – Wes Hardaker Dec 20 '13 at 22:06
  • @WesHardaker: Thanks so much, I really appreciate your help. I'll check out File::Find. – Alex A. Dec 20 '13 at 22:16

Your Answer

