在文件名末尾添加序号 - Shell 脚本
Adding sequential numbers to the end of file names - Shell Script
我正在尝试在重命名脚本期间将连续的四位数字添加到文件名的末尾。我遇到的问题 运行 是它只填充第一个文件并且添加的数字不是连续的。到目前为止,这是我的脚本:
起始文件名:
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
一如既往,非常感谢您的帮助!
那么 .. 您正在使用 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
之后,等等
许多工具可以帮助您获得 "natural" 排序顺序。特别是,如果您使用 Linux,您的 ls
和 sort
可能来自 GNU coreutils,这意味着您可以 ls -v
或 sort -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 中有 ls -v
而没有 extglob
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
对目录进行 无 排序。文件规范在某种程度上限制了视图。
grep
用于强制文件名格式,因为这种模式不能在 shell 扩展中完全表示。
sort -t- -k2n
用连字符分隔字段,然后在第二个字段上按数字排序。
- 循环中的
if
确保我们不会有人通过制作像 FILE-1.png\nFILE-2.png
. 这样的文件名来搞砸我们
要在文件名末尾添加顺序编号,您可以使用以下批处理脚本
@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/?'
引用自此
我正在尝试在重命名脚本期间将连续的四位数字添加到文件名的末尾。我遇到的问题 运行 是它只填充第一个文件并且添加的数字不是连续的。到目前为止,这是我的脚本:
起始文件名:
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
一如既往,非常感谢您的帮助!
那么 .. 您正在使用 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
之后,等等
许多工具可以帮助您获得 "natural" 排序顺序。特别是,如果您使用 Linux,您的 ls
和 sort
可能来自 GNU coreutils,这意味着您可以 ls -v
或 sort -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 中有 ls -v
而没有 extglob
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
对目录进行 无 排序。文件规范在某种程度上限制了视图。grep
用于强制文件名格式,因为这种模式不能在 shell 扩展中完全表示。sort -t- -k2n
用连字符分隔字段,然后在第二个字段上按数字排序。- 循环中的
if
确保我们不会有人通过制作像FILE-1.png\nFILE-2.png
. 这样的文件名来搞砸我们
要在文件名末尾添加顺序编号,您可以使用以下批处理脚本
@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/?'
引用自此