BASH:查找并重命名文件&目录

时间:2014-11-11 16:19:28

标签: bash sed find

我想在所有文件/目录名称中用:2f替换-,由于某种原因,下面的单行代码无法正常工作,有没有更简单的方法来实现这一目标?

目录名称示例:

AN :2f EXAMPLE

命令:

for i in $(find /tmp/ \( -iname ".*" -prune -o -iname "*:*" -print \)); do { mv $i $(echo $i | sed 's/\:2f/\-/pg'); }; done

2 个答案:

答案 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')"

同时引用所有变量和命令替换。

只要您没有包含换行符的文件名,就可以使用此功能。