我该如何递归重命名
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
要使其递归到子目录,您有两个选择:
使用递归 shell glob
shopt -s globstar rename --nopath -n 's/.*(..)\.jpg$/$1.jpg/' **/*.jpg
使用
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
// 。ksh
zsh
sh -c
你可以在 shell 循环中使用递归 glob,但您需要分离 dirname 和 basename 才能应用参数替换 ex。
for f in ./**/*.jpg; do d="${f%/*}"; b="${f##*/}"; echo mv "$f" "$d/${b: -6}"; done