pat*_*ick 62 shell zip wildcards rm
我整理了一个脚本来为我做一些文件操作。我正在使用通配符运算符*将函数应用于一种类型的所有文件,但有一件事情我不明白。我可以unzip像这样的文件夹中的所有文件
unzip "*".zip
Run Code Online (Sandbox Code Playgroud)
但是,之后要删除所有 zip 文件,我需要执行
rm *.zip
Run Code Online (Sandbox Code Playgroud)
也就是说,它不需要引号。另一方面,如果我只是给它*(给我一个“文件不匹配”的警告),解压缩将不起作用。
为什么这是不同的?对我来说,这似乎是完全相同的操作。还是我错误地使用了通配符?
Unix 中通配符的介绍并没有真正涉及到这一点,我在rm或zip文档中找不到任何内容。
我在 Mac (Yosemite) 上使用终端。
Jef*_*ler 75
你已经很好地说明了情况。拼图的最后一部分是unzip可以处理通配符本身:
http://www.info-zip.org/mans/unzip.html
论据
文件[.zip]
...
通配符表达式类似于常用的 Unix shell(sh、ksh、csh)中支持的表达式,并且可能包含:
* 匹配 0 个或多个字符的序列
通过引用 * 通配符,您可以阻止 shell 扩展它,以便unzip看到通配符并根据其自己的逻辑处理扩展它。
rm相比之下,不支持通配符自身,因此试图引用一个通配符将指示rm来寻找文件名,而不是字面星号。
unzip *.zip不起作用的原因是它unzip的语法根本不允许多个 zip 文件;如果有多个参数,它期望第二个和后续参数是存档中的文件:
解压缩 [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] 文件 [.zip] [文件 ...] [-x xfile(s) ...] [-d exdir]
cha*_*aos 25
这两个命令之间的区别是引号*字符。如果您在 shell 中调用命令并将*字符用作参数,则 shell 本身将评估该参数。看这个例子:
$ ls
file1.zip file2.zip file3.zip file4.txt
Run Code Online (Sandbox Code Playgroud)
现在有一个*:
$ ls *.zip
file1.zip file2.zip file3.zip
Run Code Online (Sandbox Code Playgroud)
shell 评估通配符并构建一个命令,如下所示:
$ ls file1.zip file2.zip file3.zip
Run Code Online (Sandbox Code Playgroud)
使用带引号的通配符,它被解释为一个名为(字面意思)的文件*.zip:
$ ls "*".zip
ls: cannot access *.zip: No such file or directory
Run Code Online (Sandbox Code Playgroud)
unzip不能使用多个压缩文件作为参数调用该实用程序。但是,开发商为此选择了另一种方式。从联机帮助页:
文件[.zip]
[...] 通配符表达式类似于常用的 Unix shell(sh、ksh、csh)中支持的那些 [...] (确保引用任何可能被操作系统解释或修改的字符,特别是在Unix 和 VMS。)
不同之处在于在第一种情况下,shell 本身扩展了 glob:
% cd /
% echo *
Applications Library Network System Users Volumes bin cores ...
%
Run Code Online (Sandbox Code Playgroud)
而在第二种情况下,应用程序本身使用该文字字符做某事™:
% cd /
% perl -E 'chdir "/tmp" or die; say for glob($ARGV[0])' "*"
com.apple.launchd.aj4FEhYqm5
...
Run Code Online (Sandbox Code Playgroud)
如果不加引号,shell 首先扩展 glob,并且该命令将使用该 shell glob 扩展到的任何内容运行。
| 归档时间: |
|
| 查看次数: |
6870 次 |
| 最近记录: |