jox*_*oxl 10 unix command-line
最近我面临着删除目录中所有文件/文件夹的任务,不包括那些匹配特定模式的文件/文件夹。所以我编写了一个单行 unix 命令来完成这项工作。必须只有一行吗?我想不是,但那样肯定更酷!
虽然问题很简单,但我对我的解决方案最终变得如此复杂感到有些惊讶。这是我使用的命令;注意:这是一个糟糕的解决方案,因为它不处理包含换行符的文件名(这在我的情况下无关紧要)。
ls | grep -v PATTERN | xargs -n1 -IREPLACE rm -rf REPLACE
Run Code Online (Sandbox Code Playgroud)
我没有使用“find”命令,因为我不想递归到匹配 PATTERN 的文件夹中。例如,考虑以下文件结构:
file_foo.txt
first_dir
|
+--> contents
+--> ...
foo_dir
|
+--> anotherfile.txt
+--> morefiles.log
foo_file.txt
somefile.txt
Run Code Online (Sandbox Code Playgroud)
使用模式“foo”必须只删除“first_dir”(当然也是它的内容)和“somefile.txt”(不是“anotherfile.txt”或“morefiles.log”)。
问题,是否有更好(更优雅和正确)的方法来实现这一目标?
编辑:
最近我注意到“查找”可能是一个更好的选择:
find * -maxdepth 0 ! -name PATTERN -print0 | xargs -0n1 rm -rf
Run Code Online (Sandbox Code Playgroud)
此解决方案可以正确处理包含换行符的路径。
Chr*_*sen 10
以下示例带有echo前缀,以便您可以在实际使用模式之前对其进行测试。删除echo以激活rm -rf。代替rm -ri提示进行确认。
ksh对其 globbing 有一个否定匹配扩展:
# ksh
echo rm -rf !(*foo*)
Run Code Online (Sandbox Code Playgroud)
如果你设置了这个选项,同样的语法在bash 中是可用的extglob:
# bash
shopt -s extglob
echo rm -rf !(*foo*)
Run Code Online (Sandbox Code Playgroud)
zsh对此有自己的语法:
# zsh
setopt extended_glob
echo rm -rf ^*foo*
Run Code Online (Sandbox Code Playgroud)
它还可以使用ksh风格的语法:
# zsh: ksh-style glob syntax
setopt ksh_glob no_bare_glob_qual
echo rm -rf !(*foo*)
# zsh: ksh-style glob syntax, adapted for the default bare_glob_qual option
setopt ksh_glob bare_glob_qual
echo rm -rf (!(*foo*))
Run Code Online (Sandbox Code Playgroud)
这是另一个find解决方案。我不确定这比你的有什么真正的优势,但它不需要xargs并允许 * 扩展到太多名称的罕见可能性。
find . -maxdepth 1 ! -name PATTERN -type f -delete
Run Code Online (Sandbox Code Playgroud)
我还添加了-type f这样它就不会尝试删除目录。
警告:-delete功能强大。我给了我的一个测试文件 0 权限,上面的命令毫不犹豫地删除了它。
| 归档时间: |
|
| 查看次数: |
12590 次 |
| 最近记录: |