How can I create a new file using a variable value as the name in Perl?

perl

Solution

Everyone here has it right, you are using single quotes in your call to `open`. Single quotes do not interpolate variables into the quoted string. Double quotes do.

my $foo  = 'cat';

print 'Why does the dog chase the $foo?';  # prints: Why does the dog chase the $foo?
print "Why does the dog chase the $foo?";  # prints: Why does the dog chase the cat?

So far, so good. But, the others have neglected to give you some important advice about `open`.

The `open` function has evolved over the years, as has the way that Perl works with filehandles. In the old days, open was always called with the mode and the file name combined in the second argument. The first argument was always a global filehandle.

Experience showed that this was a bad idea. Combining the mode and the filename in one argument created security problems. Using global variables, well, is using global variables.

Since Perl 5.6.0 you can use a 3 argument form of open that is much more secure, and you can store your filehandle in a lexically scoped scalar.

open my $fh, '>', $file or die "Can't open $file - $!\n";
print $fh "Goes into the file\n";

There are many nice things about lexical filehandles, but one excellent property is that they are automatically closed when their refcount drops to 0 and they are destroyed. There is no need to explicitly close them.

Something else worth noting is that it is considered by most of the Perl community that it is a good idea to always use the strict and warnings pragmas. Using them helps catch many bugs early in the development process and can be a huge time saver.

use strict;
use warnings;

for my $base ( 10_001..10_003 ) {

   my $file = "$base.txt";
   print "file: $file\n";

   open my $fh,'>', $file or die "Can't open the output file: $!";

   # Do stuff with handle.
}

I simplified your code a bit too. I used the range operator to generate your base numbers for the file names. Since we are working with numbers and not strings, I was able to use the `_`, as the thousands separator to improve readability without impacting the final result. Finally, I used an idiomatic perl `for` loop instead of the C style for you had.

I hope you find this helpful.

Problem

Eg: ``` $variable = "10000"; for($i=0; $i<3;$i++) { $variable++; $file = $variable."."."txt"; open output,'>$file' or die "Can't open the output file!"; } ``` This doesn't work. Please suggest a new way.

Original source