我在理解使用pax
.
背景:将.tgz
文件送入pax
并解压以获得一个装满文件的文件夹。
这是我不明白的事情:
pax -r -z -s '/.*\\//directory\\//p' -f $input_path/$tgz
其中$input_path
是 Perl 中包含路径的标量变量,$tgz
是另一个包含文件名的标量变量.tgz
。
所以-r
阅读是有意义的,-z
解压缩也很好。和-s
标志-f
让我很困惑。我收到以下错误:
pax: Invalid replacement string option /.*\\//directory\\//p
。
我认为标志是如何工作的:
-f
,因为这似乎不是问题。这就是放置文件的地方。
-s
,字符串替换修改文件中包含的文件名.tgz
。
任何人都可以揭开这/.*\\//directory\\//p
部分的神秘面纱,因为我真的不明白这里发生了什么,所有的转义斜线,\
并且p
必须做一些事情,但我不知道做什么?
答案1
Pax 解析/.*\\//directory\\//p
为:
/
是分隔符。.*\\
是正则表达式,匹配任何以反斜杠结尾的字符串(反斜杠引用下一个字符)。/
将正则表达式与替换文本分开。/
结束替换文本。directory\\//p
是尾随垃圾。
显然,您打算使用反斜杠来保护斜杠,以便它们成为正则表达式的一部分而不是分隔符。对于 shell 脚本,其中有额外的反斜杠(但它们可能是由于这种情况发生在 perl 脚本中,稍后会详细介绍)。斜线也有问题。如果你想any/leading/prefix/up/to/directory
从路径中删除,那么它应该是
pax -r -z -s '/.*\/directory\///p' -f "$input_path/$tgz"
使用不同的分隔符会更容易阅读。那么你就不需要转义斜杠了。
pax -r -z -s '!.*/directory/!!p' -f "$input_path/$tgz"
所有这一切都假设该命令是壳命令。你提到了一个 Perl 脚本; Perl 会添加自己的引用层,因此要编写的内容取决于字符串在 Perl 脚本中的插入方式。使用$input_path/$tgz
肯定是有问题的,因为它将字符串插入到 shell 脚本中,因此该字符串将被解析为 shell 片段而不是文件名。
如果 shell 命令位于双引号或反引号之间,则反斜杠确实需要加倍。仍然存在斜线错位的问题。这是用 Perl 编写的一种方法:
my $quoted_file_name = quotemeta("$input_path/$tgz");
system("pax -r -z -s '!.*/directory/!!p' -f $quoted_file_name");
如果您正在使用system
,则应该使用列表形式,以避免通过不调用中间 shell 来避免引用问题。
system('pax', '-r', '-z', '-s', '!.*/directory/!!p', '-f', "$input_path/$tgz");