通过文件名的子字符串批量重命名文件

通过文件名的子字符串批量重命名文件

我有文件

..
00016_0912RP10R6_RampMotorway9_0912RP10R6_13.646852_100.687103.jpg
00017_0912RP10R6_RampMotorway9_0912RP10R6_13.646956_100.686897.jpg
00018_0912RP10R6_RampMotorway9_0912RP10R6_13.647067_100.686684.jpg
...

我想拥有

00016.jpg
00017.jpg
00018.jpg

循环子文件夹并重命名的最佳 Linux 命令是什么?

答案1

使用find

find . -type f -name '*_*.jpg' -exec sh -c '
    for pathname do
        newname=${pathname##*/}
        newname="${pathname%/*}/${newname%%_*}.jpg"
        printf "Would move %s to %s\n" "$pathname" "$newname"
        # mv -i "$pathname" "$newname"
    done' sh {} +

这将找到当前目录中或当前目录下名称与给定模式匹配的所有常规文件的路径名。对于这些路径名的批次,将执行一个简短的 shell 脚本,该脚本循环遍历给定的路径名​​并重命名文件(为了安全起见,实际的重命名已被注释掉)。

给定一个类似 的路径名./a/b/c/foo0_some_other_bits.jpg,shell 脚本会将其转换为:./a/b/c/foo0.jpg首先删除目录(生成foo0_some_other_bits.jpg),然后删除第一个_字符之后的所有内容,然后再次将目录添加回来。路径名的目录位将被删除并替换,以防万一它也恰好包含一个或多个_字符。这是使用标准参数扩展来完成的。

使用globstarshell 选项bash

shopt -s globstar   # use "set -o globstar" in ksh93, or remove completely in zsh
for pathname in ./**/*.jpg; do
    [ -f "$pathname" ] || continue
    newname=${pathname##*/}
    newname="${pathname%/*}/${newname%%_*}.jpg"
    printf "Would move %s to %s\n" "$pathname" "$newname"
    # mv -i "$pathname" "$newname"
done

这与上面的命令完全相同find,唯一的区别是它不会找到隐藏的名称(shopt -s dotglob为此添加)。

答案2

使用参数替换的简单方法bash

for file in *.jpg; do mv "${file}" "${file/_*/.jpg}";done

如果在文件所在的目录中运行,它将循环遍历文件。

答案3

pax -rw -'s/_[^/]*\.jpg/.jpg/' -'s/.*//' . .

可能会起作用。

相关内容