我想在所有文件/目录名称中用:2f
替换-
,由于某种原因,下面的单行代码无法正常工作,有没有更简单的方法来实现这一目标?
目录名称示例:
AN :2f EXAMPLE
命令:
for i in $(find /tmp/ \( -iname ".*" -prune -o -iname "*:*" -print \)); do { mv $i $(echo $i | sed 's/\:2f/\-/pg'); }; done
答案 0 :(得分:2)
您不必解析find
:
find . -depth -name '*:2f*' -execdir bash -c 'echo mv "$0" "${0//:2f/-}"' {} \;
我们正在使用-execdir
,以便从包含找到的文件的目录中执行命令。我们还使用-depth
,以便在目录本身之前考虑目录的内容。所有这些都是为了避免在:2f
字符串出现在目录名中时出现问题。
按原样,此命令是无害的,不会执行任何重命名;它只会在终端上显示将要执行的内容。如果您对所看到的内容感到满意,请移除echo
。
这假设您要对当前目录中的所有文件和文件夹(递归)执行重命名。
-execdir
可能不适用于您的find
版本。
如果您的find
不支持-execdir
,那么您可以不加相处:
find . -depth -name '*:2f*' -exec bash -c 'dn=${0%/*} bn=${0##*/}; echo mv "$dn/$bn" "$dn/${bn//:2f/-}"' {} \;
这里,诀窍是将目录部分与文件名部分分开 - 这是我们在dn
(dirname)和bn
(基本名称)中存储的内容 - 然后只更改{{1}在文件名中。
答案 1 :(得分:1)
由于您有包含空格的文件名,for
会在迭代时将它们拆分为单独的参数。换一个while循环来管道:
find /tmp/ \( -iname ".*" -prune -o -iname "*:*" -print \) | while read -r i; do
mv "$i" "$(echo "$i" | sed 's/\:2f/\-/pg')"
同时引用所有变量和命令替换。
只要您没有包含换行符的文件名,就可以使用此功能。