如何让Perl识别带有“~”的路径?

7
可能重复:
如何在Perl中找到用户的主目录? 我正在运行Ubuntu。
每当我传递一个以~开头的路径(例如~/Documents/file.txt)给Perl脚本时,它无法找到它。我必须传递规范化的路径(例如/home/dave/Documents/file.txt)。
为什么会这样?
我能让Perl识别~路径吗?
更新
所有建议的解决方案都包括更改脚本中的代码。我希望有一个不需要对脚本本身进行任何更改的解决方案(因为它们并不都是我的)。也许是Bash工作方式的问题?
问题的更新版本发布在Super User上

可能是如何在Perl中查找用户的主目录?的重复问题。 - Cœur
7个回答

9
您可以将路径传递给glob以进行扩展。

2
在“~/a filename with spaces.txt”处出现了中断。 - j_random_hacker
1
@Ven'Tatsu:确实如此!但是奇怪的是,创建了2个文件,abcd.txte gh.txtglob"\Qabc?.txt"仅返回abc?.txt(即未展开,?不匹配d),而glob"\Qe g?.txt"却返回e gh.txt(即现在某种原因下?匹配了 h)。我的大脑很疼。 - j_random_hacker
@j_random_hacker,奇怪的是,bashcsh shell扩展在两种情况下都将由quotemeta生成的\?视为字面上的?,而不是匹配任何一个字符。我不知道为什么perl会给出不同的结果。 - Ven'Tatsu
2
j_random_hacker,glob文档明确说明该函数会在空格处分割。因此您必须加引号。glob '~/a\ filename\ with\ spaces.txt'可以正常工作。 - daxim

6

glob函数可以理解标准的Unix文件通配符。

my $file = glob('~/Documents/file.txt');

1
在“~/a filename with spaces.txt”处中断。 - j_random_hacker

6

如果您需要一种可靠(且易于使用)的跨平台方法,请尝试使用File::HomeDir

use File::HomeDir;
print File::HomeDir->my_home;

我接受这个翻译,因为我的问题最初的措辞不够好。请查看更新2获取我的“真正”的问题。 - David B

4

试着将~替换为$ENV{HOME}


@Wooble,确实,您也可以使用((getpwnam('someuser'))[7]) - Bruno

3

请使用尖括号引号(angle-quotes),而不是双引号:

open(my $fh, "< :crlf :encoding(cp1252)",
              <~/Documents/file.txt>)
    || die "couldn't open Winblose text file ~/Documents/file.txt: $!";
<xxx> 迭代操作符通常被认为是对 readline 函数的语法糖,但如果在 xxx 中出现 shell 元字符,那么它将调用 glob 函数,其中 ~ 也算作一个元字符。
你可能更喜欢使用 <:encoding(Latin1) 的打开模式,具体取决于文件本身。

3
从Bruno的评论中,你可以这样做:
$path =~ s/^~(\w*)/ ( getpwnam( $1 || $ENV{USER} ))[7] /e;
e 标记会用替换表达式的执行结果或计算结果来替换原先的表达式。

0
有点晚了,但是一个简单的解决方案是在文件名/路径中双重转义空格,这样glob就不会出错。不太确定它是否可移植,但在支持此功能的平台上(甚至可能是Windows),这样做非常容易,然后将结果值存储在一个变量中,以便于使用。可以使用正则表达式将文件名中的空格替换为双反斜杠转义。例如,不使用正则表达式的示例:
my $dir_name  = "~/Shared\\ Items/a\\ filename\\ with\\ spaces.txt";
my $glob_name = glob($dir_name);

print "exists!\n" if -e $glob_name;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接