【问题标题】:Adding sequential numbers to the end of file names - Shell Script在文件名末尾添加序列号 - Shell 脚本
【发布时间】:2016-01-08 16:45:09
【问题描述】:

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

起始文件名:

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 变量。但我仍然希望它以第一组数字的数字顺序命名第二组数字,如下面的我想要的输出所示。

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

非常感谢任何帮助!

【问题讨论】:

  • 不知道为什么有人反对这个。它包含一个好问题的所有要素——输入、期望和实际输出,甚至尝试编写解决方案。

标签: shell unix sequential batch-rename


【解决方案1】:

要在文件名末尾添加顺序编号,可以使用以下批处理脚本

@echo off
setlocal EnableDelayedExpansion
set suffix=100
for /F "delims=" %%i IN ('dir /B *.txt') do (
    set /A suffix+=1
    ren "%%i" "%%~ni_!suffix!.txt"

启用延迟扩展以获得循环内后缀变量的瞬时值。

%%~ni 用于获取不带扩展名的文件名。如需更多此类选项,只需使用 'for/?'

引用自此StackOverflow Question

【讨论】:

    【解决方案2】:

    所以..您正在使用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 中的数字去掉,首先去掉从点到结尾的所有内容,然后去掉从开头到破折号的所有内容。如果您的文件实际上没有按照您的问题进行格式化,则您必须对此进行调整。

    哦,感恩节快乐。 :-)


    每个 cmets 更新

    *.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 依赖项)来显示文件的受限视图。在解析 ls 时,您不想犯像 *.png 这样的构造错误,因为您不想花时间预测如果文件名中有换行符会发生什么。

    如果您使用的是 FreeBSD 或 OSX,或者不使用 bash,则需要额外的措施,因为在 Almquish shell 中有 ls -v 而没有 extglob

    ls -f FILE-*.png | egrep '^FILE-[0-9]+\.png$' | sort -t- -k2n | while read file; do
      if [ ! -f "$file" ]; then
        continue
      fi
    

    分解如下:

    • ls -f 对目录进行 no 排序。文件规范在一定程度上限制了视图。
    • grep 用于强制文件名格式,因为这种模式在 shell 扩展中无法完全表示。
    • sort -t- -k2n 用连字符分隔字段,然后在第二个字段上按数字排序。
    • 循环中的if 确保我们不会有人通过使用类似FILE-1.png\nFILE-2.png 的文件名来欺骗我们。

    【讨论】:

    • 感谢您的帮助,但它似乎没有按预期工作。在第 10 行中,我实际上切换了 "$n" 和 "$fn" 的顺序,但得到了这个:output.0001.testing4d.pngoutput.0001.testing4d.png 注意脚本保存为 testing.sh,因此它以某种方式将脚本名称合并到重命名中。
    • 另一件事是它没有保持它们的顺序:output.0001.testing4d.pngoutput.0001.testing4d.pngoutput.0005.testing4d.pngoutput.0007.testing4d.pngoutput.0014.testing4d.pngoutput.0002.testing4d.pngoutput.0099.testing4d.pngoutput.0008.testing4d.pngoutput.0167.testing4d.pngoutput.0003.testing4d.pngoutput.0199.testing4d.pngoutput.0004.testing4d.pngoutput.0278.testing4d.pngoutput.0005.testing4d.pngoutput.0455.testing4d.pngoutput.0006.testing4d.png
    • 脚本顶部的fmt= 行中有一个错字,我现在已修复;第二个% 被替换为$。几天没能找到我的眼镜,很抱歉造成混乱。不确定这是顺序发生了什么; for 行上的路径名扩展 *.png 应按字母/数字顺序匹配文件。使用修复后的fmt 线再试一次,看看结果是否如您所愿。
    • 谢谢你,这给了我想要的正确输出。不过,似乎仍然按照原始未填充的顺序将它们吐出。有没有办法先填充原始数字,然后在一个单独的命令中依次对它们进行编号?我在想,如果它执行两个单独的命令,它将正确排序。这有意义吗?
    • 添加了一些排序选项。不知道你运行的是什么操作系统,所以我提供了一些可移植的。
    猜你喜欢
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 2020-01-07
    • 1970-01-01
    相关资源
    最近更新 更多