如何重命名仅保留最后 N 个字符的文件

Ben*_*ich 0 command-line rename

我将如何递归重命名

Bluebellgray 19707 Rug P1.jpg
Bluebellgray Amal 1972407 Rug R1.jpg
Bluebellgray Random 1907 Rug R2.jpg
Words Amal 1707 Rug R3.jpg
Whatever 9707 Rug R4.jpg
Run Code Online (Sandbox Code Playgroud)

P1.jpg
R1.jpg
R2.jpg
R3.jpg
R4.jpg
Run Code Online (Sandbox Code Playgroud)

我只对最后 6 个字符感兴趣。

我假设答案以rename -n然后一些时髦的正则表达式开始?为了让它递归,我需要管道和重命名吗?我也只对 .jpg 文件感兴趣。

谢谢

ste*_*ver 5

在下面,-n一旦您对建议的转换感到满意,请删除。

rename

rename -n 's/.*(..)\.jpg$/$1.jpg/' *.jpg
Run Code Online (Sandbox Code Playgroud)

要使其递归到子目录中,您有两个选择:

  1. 使用递归 shell glob

    shopt -s globstar
    rename --nopath -n 's/.*(..)\.jpg$/$1.jpg/' **/*.jpg
    
    Run Code Online (Sandbox Code Playgroud)
  2. find

    find . -name '*.jpg' -execdir rename --nopath -n 's/.*(..)\.jpg$/$1.jpg/' {} +
    
    Run Code Online (Sandbox Code Playgroud)

请注意添加了--nopath防止rename命令删除前导路径元素的选项。另一种方法是.*将正则表达式模式的前导更改为[^/]*. 另请注意,如果匹配数太大(或者更准确地说,如果组合参数长度超过ARG_MAX),globstar 版本将失败。


mmv

mmv -n '*??.jpg' '#2#3.jpg'
Run Code Online (Sandbox Code Playgroud)

这个很难递归,因为它自己进行模式匹配。它可以包含在find -type d -execdir ...我想的命令中。


在这里,echo一旦您对建议的转换感到满意,请删除它。

使用一个简单的 shell 循环,假设我们可以删除包括最后一个空格字符在内的所有内容:

for f in *.jpg; do echo mv -n -- "$f" "${f##* }"; done
Run Code Online (Sandbox Code Playgroud)

您可以使用findrename命令相同的方式进行此递归:

find . -name '*.jpg' -execdir sh -c 'for f; do echo mv -n -- "$f" "${f##* }"; done' sh {} +
Run Code Online (Sandbox Code Playgroud)

请注意,如果你想使用mv "$f" "${f: -6}"的建议版本Raffa的评论,您将需要使用支持负子索引一个壳,如bash/ ksh/zshsh -c小脚本。

可以在 shell 循环中使用递归 glob,但您需要将 dirname 和 basename 分开以应用参数替换 ex。

for f in ./**/*.jpg; do d="${f%/*}"; b="${f##*/}"; echo mv "$f" "$d/${b: -6}"; done
Run Code Online (Sandbox Code Playgroud)