regex - 如何递归删除某种类型的文件

标签 regex sed find

我误读了 gzip 文档,现在我必须从彼此内部的许多目录中删除大量“.gz”文件。我尝试使用“查找”来定位所有 .gz 文件。但是,只要文件名中有空格,rm 就会将其解释为另一个文件。每当出现破折号时, rm 都会将其解释为一个新标志。我决定使用 'sed' 用“\”替换空格,用“\-”替换空格破折号,这就是我想出的。

find . -type f -name '*.gz' | sed -r 's/\ /\\ /g' | sed -r 's/\ -/ \\-/g'

例如,当我对名称为“Test - File - for - show.gz”的文件运行 find/sed 查询时,我得到输出
./Test\ \-\ File\ \-\ for\ \-\ show.gz

这对于 rm 来说似乎是可以接受的,但是当我运行时
rm $(find . -type f -name '*.gz'...)

我得到
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
...

我没有广泛使用 sed,所以我必须假设我在正则表达式上做错了什么。如果您知道我做错了什么,或者您有更好的解决方案,请告诉我。

最佳答案

在空格前添加反斜杠可保护空格免受 shell 源代码中的扩展。但是命令替换中命令的输出不经过shell解析,它只经过通配符扩展和字段拆分。在空格前添加反斜杠并不能保护它们免受字段拆分。

在破折号前添加反斜杠完全没用,因为它是 rm将破折号解释为特殊,并且不会将反斜杠解释为特殊。
find的输出通常是不明确的 - 文件名可以包含换行符,因此您不能使用换行符作为文件名分隔符。解析 find 的输出除非您使用已知的受限字符集处理文件名,否则通常会被破坏,而且它通常不是最简单的方法。
find有一个内置的方式来执行外部程序:-exec行动。没有进行解析,因此这不会受到文件名中特殊字符的任何问题的影响。 (以 - 开头的路径仍然可以解释为一个选项,但所有路径都以 . 开头,因为这是要遍历的目录。)

find . -type f -name '*.gz' -exec rm {} +

许多 find实现(Linux、Cygwin、BSD)可以在不调用外部实用程序的情况下删除文件:
find . -type f -name '*.gz' -delete

Why does my shell script choke on whitespace or other special characters?有关编写健壮的 shell 脚本的更多信息。

关于regex - 如何递归删除某种类型的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25481250/

相关文章:

python - 替换一行中第一个单词中匹配正则表达式的所有匹配项

python - 使用各种定界符处理文本文件

python - 递归搜索文件和子​​文件夹名称中的字符串列表

用于检测和删除文件中文本的 Windows 命令

excel - Find() 返回 "object variable or with block variable not set"

Xcode: "Find In Project"未找到某些文本

regex - 从文件夹创建子域,但拒绝文件夹访问

javascript - 通过正则表达式从盒子阴影中获取每个值

c# - 使用asp.net c#中的验证控件限制用户在文本框中输入html标签

macos - 为什么我的 sed {r FILE d} 函数不起作用?