![如何查找/替换文件夹名称中的字符?](https://linux22.com/image/136179/%E5%A6%82%E4%BD%95%E6%9F%A5%E6%89%BE%2F%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E5%A4%B9%E5%90%8D%E7%A7%B0%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6%EF%BC%9F.png)
我想执行以下操作:
- 查找/替换(使用正则表达式)所有出现的位置
<>:"\|?
并将其替换为空字符串 - 查找/替换(使用正则表达式)所有出现的位置
^\.+|\.+$
并将其替换为空字符串
作为测试,我手动创建了 2 个文件夹(参见屏幕截图)并运行这些文件夹:
find "/home/users/Downloads/test" -regextype sed -regex "*<>:\|?*" -type d
find "/Users/chiyo/Downloads/test" -regextype sed -regex "*[<>:\|?]*" -type d
find "/Users/chiyo/Downloads/test" -regextype sed -regex "[<>:\|?]" -type d
并没有找到任何。
我正在使用这个版本的find
.
=> find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.
有什么想法可以做到这一点吗?
答案1
前两个例子已经过时了。
*<>:\|?*
您不能以*
.*
表示 0 个或多个前一个原子。它还表示<
后跟>
后跟:
...,并且?
是一个特殊字符。*[<>:\|?]*
这更接近于您使用的角色类,但仍然是*
在一开始。[<>:\|?]
如果它是子正则表达式匹配,则它会匹配,但事实并非如此。您需要匹配整个文件名,包括目录路径。
因此,添加正则表达式代码来消耗之前和之后的内容。 (.
是任何字符,*
是前一个原子的零个或多个保证。因此.*
将匹配任何内容。)
因此尝试.*[<>:\|?].*
你不会更换这样的东西,你也没有告诉我们你想要用什么来更换它们。
答案2
使用-name
而不是-regex
(因为它是您真正感兴趣的文件名并且-regex
与整个路径匹配):
find folder -type d -name '*[<>:\|?]*'
这将找到其名称中或之下至少folder
包含字符<
、>
、:
、\
或之一的任何目录|
。?
要从目录名称中删除这些字符:
find folder -depth -type d -name '*[<>:\|?]*' \
-execdir bash -c 'mv "$1" "${1//[<>:\|?]/}"' bash {} ';'
这假设重命名目录的新名称不是现有目录的名称。添加名称冲突测试:
find folder -depth -type d -name '*[<>:\|?]*' \
-execdir bash -c '[ ! -e "${1//[<>:\|?]/}" ] && mv "$1" "${1//[<>:\|?]/}"' bash {} ';'
如果新名称已存在,这将避免尝试重命名目录
该mv
命令在子 shell 中执行bash
。shell 以找到的目录的父目录作为其工作目录来执行。它使用bash
-specific 参数替换从找到的目录的文件名中删除所有有问题的字符。
该命令还用于-depth
对 .txt 下的目录结构进行深度优先遍历folder
。如果没有这个,find
将尝试输入您刚刚重命名的目录,并且会失败。
有关的: