我正在尝试在Perl脚本中打开一个名称包含特殊字符&#34;(&#34;和&#34;)&#34;,括号的文件,但我无法这样做。< / p>
如果我有像abc_5(rt)_dgj.csv
这样的文件名,有没有办法在脚本中打开这个文件?
$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");
答案 0 :(得分:3)
不应该有任何问题。例如:
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
$
在Mac OS X 10.10.5上使用Perl 5.22.0进行测试。
现在问题有示例代码,真正的问题很明显:行
system("cat $inputfile | tr '\r' '\n' > temp");
运行
cat abc_5(rt)_dgj.csv | …
这将生成(shell)语法错误。如果您在命令行中亲自尝试,您也会看到它们。您应该将文件名括在(单引号或双引号)中:
system(qq{cat "$inputfile" | tr '\r' '\n' > temp});
以便括号不会暴露在shell中。
当您隐藏正在进行的操作时 - 不引用代码,而不引用错误消息 - 即使问题很容易解决,您仍然难以帮助您。像最后一样创建MCVE(How to create a Minimal, Complete, and Verifiable Example?)有很大帮助。它浪费的时间更少,而且浪费的时间更少。
如果名称被充分引用,在文件名中有一对括号(或甚至一个括号)并不会造成任何麻烦。正如我所指出的,双引号对于这个特定的文件名是足够的(还有很多其他文件名,甚至包含特殊字符的文件名);如ikegami noted,还有其他名称会导致问题。具体来说,包含美元符号,后引号或双引号的名称会引起双引号的悲痛;包含单引号的名称会引起单引号的悲伤。
Ikegami还指出,有一个模块String::ShellQuote,旨在解决这些问题。它不是Perl核心模块,因此您必须自己安装它,但如果您必须处理用户可能会抛出的任何反常名称,那么使用它将是明智的。
模块中shell_quote
函数的文档说:
如果无法安全引用任何字符串 shell_quote croak 。
我不清楚哪些字符串无法安全引用;文档没有详细说明这个问题。 (croak
是一个名为Carp的核心模块的方法。)