Reputation: 169
I am trying to open a file whose name contains special characters "(" and ")", parentheses, in a Perl script and I am unable to do so.
If I have a file name like abc_5(rt)_dgj.csv
, is there a way to open this file in the script?
$inputfile = <STDIN>;
chomp($inputfile);
unless(-e $inputfile) {
usage("Input file not present\n");
exit 2;
}
system("cat $inputfile | tr '\r' '\n' > temp");
$inputfile = "temp";
# do something here, like copy the data from inputfile and write to another file
system("rm temp");
Upvotes: 0
Views: 2102
Reputation: 753970
There shouldn't be any problem. For example:
rd.pl
#!/usr/bin/env perl
use strict;
use warnings;
my $file = "abc_5(rt)_dgj.csv";
open my $fh, "<", $file or die "A horrible death";
my $line = <$fh>;
print $line;
close $fh;
$ cat > "abc_5(rt)_dgj.csv"
Record 1,2014-12-30,19:43:21
$ perl rd.pl
Record 1,2014-12-30,19:43:21
$
Tested with Perl 5.22.0 on Mac OS X 10.10.5.
Now the question has sample code, the real problem is obvious: the line
system("cat $inputfile | tr '\r' '\n' > temp");
runs
cat abc_5(rt)_dgj.csv | …
and that will generate (shell) syntax errors. If you try it for yourself at the command line, you'll see them too. You should enclose the file name in (single or) double quotes:
system(qq{cat "$inputfile" | tr '\r' '\n' > temp});
so that the parentheses are not exposed in the shell.
When you hide what's going on — not quoting the code, not quoting the error message — you make it hard for people to help you even though the problem is easy to resolve. Creating an MCVE (How to create a Minimal, Complete, and Verifiable Example?), as you did in the end, helps enormously. It wastes less of your time, and it wastes less of our time.
Having a pair of parentheses (or even one parenthesis) in a file name of itself doesn't cause any trouble if the name is quoted sufficiently. As I noted, double quotes are adequate for this specific file name (and a good many others, even ones containing special characters); as ikegami noted, there are other names that will cause problems. Specifically, names containing dollar signs, back quotes or double quotes will cause grief with double quotes; names containing single quotes will cause grief with single quotes.
Ikegami also notes that there is a module, String::ShellQuote, which is designed to deal with these problems. It is not a Perl core module so you would have to install it yourself, but using it would be sensible if you have to deal with any perverse name that the user might throw your way.
The documentation for the shell_quote
function from the module says:
If any string can't be safely quoted shell_quote will croak.
I'm not clear what strings can't be safely quoted; the documentation doesn't elaborate on the issue. (croak
is a method from the core module called Carp.)
Upvotes: 3