shell - 在文件名末尾添加序列号 - Shell 脚本

标签 shell unix sequential batch-rename

我试图在重命名脚本期间将连续的四位数字添加到文件名的末尾。我遇到的问题是它只填充第一个文件并且添加的数字不是连续的。到目前为止,这是我的脚本:

起始文件名:

FILE-1.png
FILE-5.png
FILE-14.png
FILE-99.png
FILE-167.png
FILE-199.png
FILE-278.png
FILE-455.png

脚本:
a=`printf '%04d' "1"`

cd /${1-$PWD}

for i in *.png;
    do mv $i `printf output.%04d.$a.png $(echo $i | sed 's/[^0-9]*//g')`;
    let a=a+1 
done

编辑:
我对脚本做了一些改动,加入了 fmt变量在顶部。但我仍然希望它按照第一组数字的数字顺序命名第二组数字,如下面的 Desired 输出所示。
fmt=output.%04d
n=1

cd /${1-$PWD}

for i in *.png;
    do mv $i `printf $fmt.%04d.png $(echo $i | sed 's/[^0-9]*//g') "$n"`;
    n=$((n+1))
done

我的新输出:
output.0001.0001.png
output.0005.0007.png
output.0014.0002.png
output.0099.0008.png
output.0167.0003.png
output.0199.0004.png
output.0278.0005.png
output.0455.0006.png

原始输出:
output.0001.0001.png
output.0005.7.png
output.0014.2.png
output.0099.8.png
output.0167.3.png
output.0199.4.png
output.0278.5.png
output.0455.6.png

期望的输出:
output.0001.0001.png
output.0005.0002.png
output.0014.0003.png
output.0099.0004.png
output.0167.0005.png
output.0199.0006.png
output.0278.0007.png
output.0455.0008.png

与往常一样,非常感谢任何帮助!

最佳答案

所以..你正在使用printf用于格式化。这是一个好的开始。但是您并没有始终如一地使用它。未格式化的部分.. 为什么不格式化呢?

#!/bin/sh

fmt="output.%04d.%04d.png"

cd /${1-$PWD}

n=1
for file in *.png; do
    fn="${file%.*}"; fn="${fn#*-}"
    mv "$file" "$(printf "$fmt" "$fn" "$n")"
    n=$((n+1))
done

请注意,循环中的第一行只是从 $file 中去除了数字。 ,首先去掉从点到结尾的所有内容,然后去掉从开始到破折号的所有内容。如果您的文件实际上没有按照您的问题进行格式化,则您必须对此进行调整。

哦,感恩节快乐。 :-)

根据评论更新
*.png上面的扩展显然会按字母顺序排列,这样你 FILE-5.png关注 FILE-455.png , 等等。

许多工具可以帮助您获得“自然”的排序顺序。特别是,如果您使用的是 Linux,您的 lssort可能来自 GNU coreutils,这意味着您可以 ls -vsort -V以获得自然的排序顺序。但是您没有指定您使用的是 Linux,此外,parsing ls is a bad idea .但是 bash 的内部模式匹配和路径名扩展不能处理自然排序。

在这种特殊情况下,由于您正在处理(至少在您的问题中)格式高度可预测的文件名,我们可能可以安全地解析 ls输出并使用命令行工具对其进行排序。

如果您使用 Linux 和 bash,for上面的行可以替换为:
shopt -s extglob
ls -v FILE-+([0-9]).png | while read file; do

这将设置 bash 的 extglob shell 选项,然后使用 ls -v (这是 Linux 依赖项)以显示文件的受限 View 。在解析 ls 时,你不想犯像 *.png 这样的构造错误,因为您不想花时间预测如果文件名中有换行符会发生什么。

如果您使用的是 FreeBSD 或 OSX,或者没有使用 bash,则需要额外的措施,因为有 ls -v并且没有 extglob在 Almquish shell 中:
ls -f FILE-*.png | egrep '^FILE-[0-9]+\.png$' | sort -t- -k2n | while read file; do
  if [ ! -f "$file" ]; then
    continue
  fi

这分解如下:
  • ls -f不对目录进行排序。文件规范在某种程度上限制了 View 。
  • grep用于强制执行文件名格式,因为这种模式不能在 shell 扩展中完全表示。
  • sort -t- -k2n用连字符分隔字段,然后在第二个字段上按数字排序。
  • if在循环内部,通过创建类似 FILE-1.png\nFILE-2.png 的文件名来确保我们不会有人在搞砸我们。 .
  • 关于shell - 在文件名末尾添加序列号 - Shell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33060216/

    相关文章:

    linux - 修改 tar 存档中嵌套的文件

    JQuery 在 keyup 后启动 2 个回调

    ms-access - SQL Server 2000,查询是否按顺序执行?

    windows - [ : too many arguments on Cygwin Shell script

    bash - 在 bash 中有效获取命令输出的一致语法?

    bash - 使用 sed 命令解析资源 Visual Studio .rc 文件

    linux - 远程登录传递命令然后等待并传递命令

    c - C 中的守护进程 - 有没有一种方法可以实现它们?

    node.js - 如何安装分离到 Git 子模块的 NPM 应用程序(在 Docker 容器内)

    python - 在colab上-class_weight导致ValueError : The truth value of an array with more than one element is ambiguous.使用a.any()或a.all()