bash 重命名 file/add 文件名中的整数,在多个子目录中具有各种扩展名

bash rename file/add integer in filename with various extensions in multiple subdirectories

我想使用 bash 将一个整数插入到多个子目录中具有各种扩展名的文件名中。

示例:

我试图将文件名与扩展名分开,并在两者之间插入整数:

i=123
find . -type f -exec sh -c ' echo mv "[=12=]" "${0%.*}${i}.${0##*.}" ' {} \;
mv ./trial2/foo.hhh ./trial2/foo.hhh

但是变量输出${i}没有打印出来。为什么?
如果我改为:

find . -type f -exec sh -c ' mv "[=13=]" "${0%.*}123.${0##*.}" ' {} \;
mv ./trial2/foo.hhh ./trial2/foo123.hhh

号码已打印。但是,我需要变量 ${i} 因为它将在包装 for 循环中定义。

编辑

你快到了;你只是打了一个引用的微妙之处。 i 在当前 shell 中声明,因此需要通过 find 以某种方式传递到 sh 运行 中。在您当前的命令中,${i} 是单引号,因此在将引用的 material 传递给 sh.

之前,bash 不会对其进行解释

正如查尔斯·达菲所建议的那样:

find . -type f -exec sh -c ' echo mv "[=10=]" "${0%.*}.${0##*.}" ' {} "$i" \;

sh 命令中,[=19=] 就是 {},如您所知。 </code> 是 <code>sh 的第二个参数,即 "$i"i 扩展为单个单词)。 sh 命令不是 ${i},而是使用 </code> 来访问该参数(<code>i 的副本)。

原创

在这个例子中,i被插入到当前的shell中。

Before: find . -type f -exec sh -c ' echo mv "[=11=]" "${0%.*}${i}.${0##*.}" ' {} \;
After:  find . -type f -exec sh -c ' echo mv "[=11=]" "${0%.*}'"${i}"'.${0##*.}" ' {} \;
                                                          ^^    ^^

'"${i}"' 将您从单引号中删除,然后扩展 i,然后将您带回单引号中。这样,您传递给 sh 的命令包含您想要的 i 的值。

[=12=] 中传递 $i,在 </code> 中传递你的文件名,然后你可以从 <code>-exec ... {} \; 更改为 -exec ... {} +,因此仅使用一个 sh 实例可以重命名多个文件。

以下需要 bash,但生成的 mv 命令即使在存在恶意或混淆文件名(包含空格、换行符、控制字符等)的情况下也保证是正确的:

find . -type f -exec bash -c '
  logcmd() { printf "%q " "$@"; printf "\n"; }  # a more accurate replacement for echo
  for f; do
    logcmd mv "$f" "${f%.*}[=10=].${f##*.}"
  done' "$i" {} +