1

Although I found many posts on how to open a file in a for loop in perl, I am having a specific issue in creating a file within a directory ( which is also the array variable)-

I am opening a file using

foreach my $dir (@listofdirs) {

open (my $OUTFILE, '>', "$dir/$dir.txt") or die "$!"; 

, this does not create a file and gives me an error No such file or directory.

If i just use open (my $OUTFILE, '>', "$dir.txt") or die; It works and creates a file under main directory from where I execute the script.

How can I control/specify the path so that it opens a file inside each $dir variable (directory)? I am sorry if this has been addressed earlier, but I am not sure what is the right way to specify the path for the new files.

Edit -

Can I change directory where the file is being created inside the loop and assign it the $dir variable value everytime?

11
  • 2
    What error do you receive? What is the value of $dir? Commented Mar 17, 2016 at 19:38
  • 4
    or die; isn't going to tell you what went wrong. You could add or die "Failed to open $dir/$dir.txt: $!" to every open call... or you can remove the or die and instead add use autodie at the top of your program. Now if file functions like open fail they will automatically die with a descriptive error message. Commented Mar 17, 2016 at 19:40
  • value of $dir would be a directory like folder1, folder2 etc that is getting populated from listofdirs - which has list of many such folders in it. The error I get is Died at this open (my $OUTFILE, '>', "$dir/$dir.txt") line Commented Mar 17, 2016 at 19:41
  • @AnkP Like Schwern mentioned, you need to either use autodie; to get the real error message or open (my $OUTFILE, '>', "$dir/$dir.txt") or die "$!"; Commented Mar 17, 2016 at 19:44
  • the task is to read each directory name from the list of directories and create a file inside that directory or $dir variable. Right now my script creates all files under the directory which has the list of directories. Commented Mar 17, 2016 at 19:44

1 Answer 1

6

Without seeing your error message, I have a pretty good idea what's wrong.

foreach my $dir (@listofdirs) {
    open (my $OUTFILE, '>', "$dir/$dir.txt") or die; 
    ...
}

I'm going to guess @listofdirs contains things like /foo/bar or foo/bar/baz/ and thus "$dir/$dir.txt" will create some funny filepaths.

$dir                      "$dir/$dir.txt"
/foo/bar                  /foo/bar//foo/bar.txt
foo/bar/                  foo/bar//foo/bar/.txt
foo/                      foo//foo/.txt

Most of these aren't going to work for various reasons. /foo/bar//foo/bar.txt will require that the directory /foo/bar/foo/ already exists. foo/bar//foo/bar/.txt is an invalid path.

"$dir/$dir.txt" is a funny construct anyway. Are you sure that's what you meant to do?


To figure out what's gone wrong you can add an some information to your error message. The traditional way is to write it all out long hand on every open call.

foreach my $dir (@listofdirs) {
    open (my $OUTFILE, '>', "$dir/$dir.txt")
        or die "Can't open '$dir/$dir.txt': $!";
    ...
}

Now you'll see what it tried to open, and why it failed (contained in $!). This rapidly gets tiresome and inconsistent, so it's better to let autodie do it for you.

# at the top of your code along with things like "use strict"
use autodie;

...

foreach my $dir (@listofdirs) {
    open (my $OUTFILE, '>', "$dir/$dir.txt");
    ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Schwern, you were right, I am getting error that no such file or directory exist. My goal is to create a file inside each directory listed in the array, as I mentioned my command is creating new files in the main directory as I am not able to direct the path correctly!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.