在Perl中打开文件名中包含特殊字符的文件

时间:2015-08-22 05:47:42

标签: macos perl

我正在尝试在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");

1 个答案:

答案 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的核心模块的方法。)