Jac*_*ite 10 command-line bash
我遇到了通配符模式和通配符,我特别感兴趣的是[!].
此构造与 构造类似
[!],不同之处在于它不匹配括号内的任何字符,而是匹配任何字符,只要它不在[和之间列出]。
rm myfile [!192]
Run Code Online (Sandbox Code Playgroud)
我相信以上内容将删除任何/所有文件,但名称中包含 192 的任何/所有文件除外。
然而,我担心在文件扩展名中正确使用它,尤其是在多个条件下。
在这种情况下,正确的语法是什么?
rm myfile [!.gif .csv. mp3]
Run Code Online (Sandbox Code Playgroud)
或者
rm myfile [!.gif !.csv !.mp3]
Run Code Online (Sandbox Code Playgroud)
我担心句号可能放错了位置,因此当我试图对特定文件进行操作时,任何带有 a .(肯定是其中任何一个?)的文件都会被操作。
此构造与 构造类似[ ],不同之处在于它不匹配括号内的任何字符,而是匹配任何字符,只要它不在[和之间列出]。
(引自http://www.tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm)
现在; 对我来说,这表明单数!就足够了,之后的所有值都包含在该范围内。
des*_*ert 17
引用man 7 glob:
An expression "[!...]" matches a single character, namely any character
that is not matched by the expression obtained by removing the first '!' from it.
(Thus, "[!]a-]" matches any single character except ']', 'a' and '-'.)
Run Code Online (Sandbox Code Playgroud)
这里强调单字符部分,[]不能用于 Bash 模式匹配中的整个字符串。
bash的Brace Expansion可用于匹配字符串,但是没有办法(我知道)否定它们。例如
1.{gif,csv,mp3}
Run Code Online (Sandbox Code Playgroud)
扩展为
1.gif 1.csv 1.mp3
Run Code Online (Sandbox Code Playgroud)
不管这些文件是否存在。
正如wchargin 所指出的,shopt可用于启用扩展模式匹配运算符,其中之一是!(). 运行后shopt -s extglob,例如
1.!(gif|csv|mp3)
Run Code Online (Sandbox Code Playgroud)
扩展为
1.jpg 1.bmp 1.png
Run Code Online (Sandbox Code Playgroud)
如果这些文件存在于当前目录中。更多阅读man bash(扩展/路径名扩展部分)和路径名扩展(通配)。
对于你想要做的事情,我总是使用find,它提供否定等等,例如以下列方式:
find . -maxdepth 1 -type f ! -name "*.gif" -a ! -name "*.csv" -a ! -name "*.mp3"
Run Code Online (Sandbox Code Playgroud)
这只是列出了结果,如果你想删除它们,只需将-delete选项附加到命令的末尾。与删除操作一样:始终首先仔细检查。
find提供了大量有用的选项,由man find.
pLu*_*umo 10
我认为您误解了括号的使用。[abc]匹配一个字符a,b或c。[!abc]匹配一个不是 a,b或 的字符c。所以命令
rm myfile [192]
Run Code Online (Sandbox Code Playgroud)
将删除myfile和文件1,9而且2因为你有Myfile和支架之间的空间。相比之下,命令
rm myfile[192]
Run Code Online (Sandbox Code Playgroud)
将删除文件myfile1,myfile9和myfile2.
括号[ ]表示字符类。其中的任何单个字符都可以在给定位置匹配。所以
file[192]
Run Code Online (Sandbox Code Playgroud)
匹配三个可能的名称:
file1
file2
file9
Run Code Online (Sandbox Code Playgroud)
它不匹配file192,因为它只有在对单字符交易file。
我们也可以在括号中使用范围。[0-9]匹配给定位置的任何单个数字。对于两位数,我们需要[0-9][0-9]. 对于后跟大写字母的数字,我们可以使用[0-9][A-Z]...
! 表示否定。
file[!192]
Run Code Online (Sandbox Code Playgroud)
将匹配在fileexcept1或9或之后具有任何单个字符的文件2。例如,它将匹配file7andfiles和file%(以及许多其他的)但不 匹配file192,因为它有两个额外的字符。
对于您的用例,我建议使用find而不是[!]. 它有一个not操作员。
它也是递归的,这意味着它默认进入所有子目录。您可以使用 将其限制在当前目录中-maxdepth 1,如果这是您想要的。Shell 通配符(通配符)是非递归的(尽管**可以启用递归通配符)。
假设您不想避免删除符号链接,我们可以添加-type d否定测试以避免删除任何目录。感谢 Eliah Kagan 的建议。
find /path -maxdepth 1 -not \( -type d -or -iname "*.gif" -or -iname "*.csv" -or -iname "*.mp3" \)
Run Code Online (Sandbox Code Playgroud)
如果你看到你想要的,你可以再次运行命令 -delete
find /path -maxdepth 1 -not \( -type d -or -iname "*.gif" -or -iname "*.csv" -or -iname "*.mp3" \) -delete
Run Code Online (Sandbox Code Playgroud)