我在CentOS服务器上的目录(和许多子目录)中有一堆文件,这些文件的扩展名意外地卡在了基本名称上。
12345jpg
我想将它们全部重命名为
12345.jpg
我已经关闭了此命令,但不能完全使重命名正则表达式起作用。
find . -type f ! -name "*.*" -exec rename 's/([0-9]{5})(.*)/$1.$2/'
更新:使用sed而不是重命名会更好吗?像这样? (目前也无法正常运行)
find . -type f ! -name "*.*" -exec sed -i '' s/([0-9]{5})(.*)/1.2/g {} ;
答案 0 :(得分:1)
我认为rename
实用程序不能处理反向引用。
这是仅适用于posix的便携式解决方案:
find . -type f -name '[0-9][0-9][0-9][0-9][0-9]?*' \
-not -name '*.*' |while IFS= read file; do
dir="${file%/*}"
file="${file#$dir/}"
B="${file#?????}"
A="${file%$B}"
mv -i "$dir/$file" "$dir/$A.$B"
done
这使用shell遍历(缺少量词,因此没有冗余)来确保我们仅重命名具有预期的五个前导数字,然后至少包含一个字符的文件,同时排除名称中带有点的文件。
然后,它逐行循环(是的,如果文件名中有换行符,这会中断,请不要这样做!)。我明确清除了$IFS
,因此空格不会解释为字段分隔符。
在while循环中,我按摩文件名。首先,我提取目录名称(如果没有,则为./
;如果偏离find . …
,请小心),然后更改$file
变量以仅存储文件名。然后,我为缺少前五个字符的文件名分配$B
(find
已经是数字),而$A
则是前五个字符。现在,我们可以使用多余的点进行重命名了。
我使用mv -i
作为安全措施。这将以交互方式询问您要覆盖的所有内容。
答案 1 :(得分:0)
您需要适当地转义正则表达式,并在替换中使用\1.\2
s/\([0-9]\{5\}\)\(.*\)/\1.\2/
例如:
$ echo '12345jpg' | sed 's/\([0-9]\{5\}\)\(.*\)/\1.\2/'
12345.jpg