我有一组按数字顺序排列的文件名,如下所示:
13B12363_1B1_0.png
13B12363_1B1_1.png
13B12363_1B1_2.png
13B12363_1B1_3.png
13B12363_1B1_4.png
13B12363_1B1_5.png
13B12363_1B1_6.png
13B12363_1B1_7.png
13B12363_1B1_8.png
13B12363_1B1_9.png
13B12363_1B1_10.png
[...]
13B12363_1B1_495.png
13B12363_1B1_496.png
13B12363_1B1_497.png
13B12363_1B1_498.png
13B12363_1B1_499.png
经过一些后处理,我删除了一些文件,我想更新订购号并用新位置替换实际编号。看着这个previous question我最终做了类似的事情:
(1) ls -v |猫 -n |当读 n f 时; mv -i $f ${f%%[0-9]+.png}_$n.png;完成
但是,此命令无法识别“订购号+ png”,而只是将新编号附加在文件名末尾。类似于 13B12363_1B1_10.png_9.png
另一方面,如果我这样做:
(2) ls -v * |猫 -n |当读 n f 时;执行 mv $f ${f%.*}_$n.png;完成
添加订购号没有问题。像13B12363_1B1_10_9.png
因此,对于(1),我似乎没有正确指定digit
,但我无法找到正确的语法。到目前为止,我尝试了 [0-9]
、[0-9]+
、[[:digits:]]
和 [ [:数字:]]+
。哪一个应该是正确的?
此外,在(2)中我想知道如何指定rename
(CentOS版本)来删除第二个和第三个下划线之间的数字。在这里我不得不说我有一些文件名,例如 20B12363_22_10_9.png
,所以我应该以某种方式指定第二个和第三个下划线。
最佳答案
使用 Bash 的内置基本正则表达式引擎和 null
分隔的文件列表。
使用示例进行测试
#!/usr/bin/env bash
prename=$1
# Bash setting to return empty result if no match found
shopt -s nullglob
# Create a temporary directory to prevent file rename collisions
tmpdir=$(mktemp -d) || exit 1
# Add a trap to remove the temporary directory on EXIT
trap 'rmdir -- "$tmpdir"' EXIT
# Initialize file counter
n=0
# Generate null delimited list of files
printf -- %s\\0 "${prename}_"*'.png' |
# Sort the null delimited list on 3rd field numeric order with _ separator
sort --zero-terminated --field-separator=_ --key=3n |
# Iterate the null delimited list
while IFS= read -r -d '' f; do
# If Bash Regex match the file name AND
# file has a different sequence number
if [[ "$f" =~ (.*)_([0-9]+)\.png$ ]] && [[ ${BASH_REMATCH[2]} -ne $n ]]; then
# Use captured Regex match group 1 to rename file with incrementing counter
# and move it to the temporary folder to prevent rename collision with
# existing file
echo mv -- "$f" "$tmpdir/${BASH_REMATCH[1]}_$((n)).png"
fi
# Increment file counter
n=$((n+1))
done
# Move back the renamed files in place
mv --no-clobber -- "$tmpdir/*" ./
# $tempdir removal is automatic on EXIT
# If something goes wrong, some files remain in it and it is not deleted
# so these can be dealt with manually
如果结果符合您的预期,请删除echo
。
示例的输出
mv -- 13B12363_1B1_495.png /tmp/tmp.O2HmbyD7d5/13B12363_1B1_11.png
mv -- 13B12363_1B1_496.png /tmp/tmp.O2HmbyD7d5/13B12363_1B1_12.png
mv -- 13B12363_1B1_497.png /tmp/tmp.O2HmbyD7d5/13B12363_1B1_13.png
mv -- 13B12363_1B1_498.png /tmp/tmp.O2HmbyD7d5/13B12363_1B1_14.png
mv -- 13B12363_1B1_499.png /tmp/tmp.O2HmbyD7d5/13B12363_1B1_15.png
关于bash - 更新文件名中的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64239192/