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

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

我该如何递归重命名

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

P1.jpg
R1.jpg
R2.jpg
R3.jpg
R4.jpg

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

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

谢谢

答案1

接下来,-n一旦您对建议的转换感到满意,就删除。

rename

rename -n 's/.*(..)\.jpg$/$1.jpg/' *.jpg

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

  1. 使用递归 shell glob

    shopt -s globstar
    rename --nopath -n 's/.*(..)\.jpg$/$1.jpg/' **/*.jpg
    
  2. 使用find

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

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


mmv

mmv -n '*??.jpg' '#2#3.jpg'

这个很难实现递归,因为它有自己的模式匹配。它可以find -type d -execdir ...我认为应该被包裹在命令中。


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

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

for f in *.jpg; do echo mv -n -- "$f" "${f##* }"; done

find您可以使用与命令相同的方式进行递归rename

find . -name '*.jpg' -execdir sh -c 'for f; do echo mv -n -- "$f" "${f##* }"; done' sh {} +

mv "$f" "${f: -6}"请注意,如果您想使用拉法的评论您需要使用支持负子字符串索引的 shell 之一,例如,对于scriptlet使用bash// 。kshzshsh -c

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

for f in ./**/*.jpg; do d="${f%/*}"; b="${f##*/}"; echo mv "$f" "$d/${b: -6}"; done

相关内容