很多类似的问题都被问到了。错误可能正盯着我的脸,但我就是看不到它......
#!/bin/bash
declare -a files
shopt -s nullglob
files=(*)
count=36 # offset
for oldfilename in "${files[@]}"; do
(( count++ ))
# newfilename=$(echo "$oldfilename" | sed -e "s/^[1-9][0-9]?\.jpg/Scount\.png/")
# newfilename=${oldfilename/[1-9][0-9]?/Scount}
# newfilename=${oldfilename/[1-9][0-9]?/"Scount"}
newfilename=${oldfilename//[1-9][0-9]?/Scount}
echo mv -fv /path1/to/"${oldfilename}" /path2/to/"${newfilename}"
done
exit 0
我尝试过注释行。我不知道/
和//
in之间的区别newfilename=${oldfilename/[1-9][0-9]?/"Scount"}
。 o_0?
编辑:
由 表示的文件的$oldfilename
格式1.jpg
为99.jpg
.输出文件的$newfilename
格式预计为 37.png 到 135.png(至少就调用而言sed
)。
不知何故,文件没有被重命名,并且点.jpg
消失了。为什么这不起作用?
答案1
我从你的(注释掉的)sed
命令中猜想你想要匹配并替换正则表达式:[1-9][0-9]?
,意思是
- 非零数字 (
[1-9]
),后跟 - 零或一位数字 (
[0-9]?
)
这是一个相当常见的正则表达式,适用于 1 到 99 之间的整数(没有前导零)。但是, 不使用正则表达式,它使用路径名扩展模式(也称为通配符)。所以意味着${parameter/pattern/string}
[1-9][0-9]?
- 非零数字 (
[1-9]
),后跟 - 一个数字 (
[0-9]
),后跟 - 任意字符 (
?
)
尽管如此,它应该适用于两位数的文件名,尽管它会消耗 并重.
命名10.jpg
为46jpg
(不带.
)。
关于您问题的其他部分,
//
替换所有出现的图案,而/
仅替换第一个。例如,
$ i=cataract
$ echo "${i/a/X}"
cXtaract
$ echo "${i//a/X}"
cXtXrXct
答案2
如果您有 Perl rename
(有时称为prename
),您可以执行以下操作:
rename -v 's!(\d+)(.*)\.jpg$!sprintf "%d%s.png", $1+36, $2!e' *.jpg
这将获取每个文件名,拆分前导数字、文件名组件的其余部分以及尾随.jpg
.然后,它将数字部分添加 36,添加原始文件名的其余部分,并将后缀替换为.png
.
使用rename -n ...
来查看它更改任何内容会发生什么,或者删除它-v
以使其静默运行。