将前导零添加到文件名的整数部分

Add leading zeros to integer section of filename

我有图像文件夹,名称如 HolidaySnapsJune-1.tifHolidaySnapsMay-12.tifHolidaySnaps2018-005.tif

我想在文件名的 整数部分 添加一个前导 0,如果它是 2 位长,如果它只是一位,我想添加两个前导 00长.

我试过

的变体
find . -name '*\_[0-9][0-9].tif' -exec sh -c '
for fpath do
  echo mv "$fpath" "${fpath%/*}/${fpath##*/}"
done' _ {} +

但是这些将前导零放在完整文件名前面而不是整数部分前面。

我很想这样做是一个 bash 脚本,它可以递归地处理文件夹,因此重要的是忽略或解决“-”前面的名称差异。

我在 Windows 并且可以访问 git-bash 中内置的任何内容,所以 bash、sed、awk 等

您可以使用 linux-utils 中的 rename.ul 命令。

rename [options] expression replacement file...

将传递给命令的所有文件名中第一次出现的 expression 替换为 replacement

假设您的文件名只包含一个连字符 -,您可以在支持 **/* glob 语法的 shell 中简单地 运行 以下两个命令(或者,使用 find-exec 选项或类似的东西)递归重命名所有文件:

rename.ul -- - -00  **/*-?.tif
rename.ul -- - -0  **/*-??.tif

rename.ul 有几个选项可以防止您不小心重命名不想要的文件(小心!后果可能非常严重):

-v, --verbose
       Show which files were renamed, if any.

-n, --no-act
       Do not make any changes; add --verbose to see what  would
       be made.

-i, --interactive
       Ask before overwriting existing files.

因此您可以 运行 带有 -nv 选项的命令来执行 dry-run 并查看程序会进行哪些更改,或者添加 -i每次重命名文件时都要求确认。

如果您不想使用 non-standard 命令并编写一个小脚本,这将是一种方法。

while read -r line; do
    num=$(sed 's/\..*//' <<<${line/*-})
    printf -v new_name '%s-%03d.%s' "${line/-*}" "${num}" "${line/*\.}"
    mv -v "${line}” "${new_name}"
done < <(printf '%s\n' HolidaySnapsJune-1.tif HolidaySnapsMay-12.tif)

下面使用HolidaySnapsJune-1.tif进行解释:

  • ${line/*-} 删除破折号前的所有内容 -= 1.tif
  • ${line/*\.} 删除扩展名以外的所有内容。
  • sed 's/\..*//' <<<${line/*-} 也删除了第一个句点 . 之后的所有内容,所以现在我们只需要 1
  • '%s-%03d.%s' 其中的 %03d 部分告诉 printf 打印前导零最多 3 位的数字。

使用 while read 因为它很容易制作模型。您可能想使用 find 命令或类似的东西作为循环的输入。

因此,在查看了此处和其他地方提交的答案之后,这就是我的想法:

find . -name '*\-[0-9][0-9].tif' -exec sh -c '
for f do
  mv "$f" "${f//\-/\-0}";
  echo "$f"
done' _ {} +

这适用于整数部分有两位数字的文件,使它们最多为 3 位数字。对于个位数的文件,我稍作改动,然后再次 运行。

此脚本的一个好处是它适用于子文件夹。

我不得不承认我没有完全理解它。我不知道为什么 done 后面跟着 ' _ {} + 。我想这是我接下来要查找的内容:-)。