我误读了gzip文档,现在我必须从许多目录中删除大量的".gz"文件.我尝试使用'find'来查找所有.gz文件.但是,只要名称中有空格的文件,rm就会将其解释为另一个文件.只要有破折号,rm就会将其解释为新旗帜.我决定用'sed'用"\"代替空格,用空格破坏用"\ - "代替,这就是我想出来的.
find . -type f -name '*.gz' | sed -r 's/\ /\\ /g' | sed -r 's/\ -/ \\-/g'
Run Code Online (Sandbox Code Playgroud)
当我在一个文件上运行find/sed查询时,例如,其名称为"Test - File - for - show.gz",我得到了输出
./Test\ \-\ File\ \-\ for\ \-\ show.gz
Run Code Online (Sandbox Code Playgroud)
这对于rm来说似乎是可以接受的,但是当我跑步时
rm $(find . -type f -name '*.gz'...)
Run Code Online (Sandbox Code Playgroud)
我明白了
rm: cannot remove './Test\\': No such file or directory
rm: cannot remove '\\-\\': No such file or directory
rm: cannot remove 'File\\': No such file or directory
rm: cannot remove '\\-\\': No such file or directory
...
Run Code Online (Sandbox Code Playgroud)
我没有广泛使用sed,所以我不得不假设我在使用正则表达式做错了.如果你知道我做错了什么,或者你有更好的解决方案,请告诉我.
在空格之前添加反斜杠可以保护空间免受shell源代码中的扩展.但是命令替换中的命令输出不进行shell解析,只进行通配符扩展和字段拆分.在空格之前添加反斜杠不会保护它们免受字段拆分.
在破折号之前添加反斜杠是完全无用的,因为它将rm
破折号解释为特殊,并且它不会将反斜杠解释为特殊.
输出find
通常是不明确的 - 文件名可以包含换行符,因此您不能使用换行符作为文件名分隔符.解析输出find
通常会被破坏,除非您在已知的受限字符集中处理文件名,并且它通常不是最简单的方法.
find
有一种内置的方式来执行外部程序:-exec
动作.没有进行解析,因此文件名中的特殊字符不会出现任何问题.(开头的路径-
仍然可以解释为一个选项,但所有路径都以此开头,.
因为这是遍历的目录.)
find . -type f -name '*.gz' -exec rm {} +
Run Code Online (Sandbox Code Playgroud)
许多find
实现(Linux,Cygwin,BSD)可以在不调用外部实用程序的情况下删除文件:
find . -type f -name '*.gz' -delete
Run Code Online (Sandbox Code Playgroud)
请参阅为什么我的shell脚本会在空格或其他特殊字符上出现问题?有关编写健壮的shell脚本的更多信息.