使用反引号或$()与xargs和sed或awk

nrz*_*nrz 5 bash awk sed xargs

假设我想要更改一些jpg.jpg.jpg(以bash为单位)结束的文件名,并且我想通过将输出汇总findxargs:

使用sed:

find . -iname '*jpg.jpg' | xargs -I % mv -iv % $(echo % | sed 's/jpg.jpg/.jpg/g')
Run Code Online (Sandbox Code Playgroud)

然而,这并不能取代jpg.jpg.jpg中的目标文件mv.

使用awk:

find . -iname '*jpg.jpg' | xargs -I % mv -iv % $(echo % | awk '{gsub(/jpg.jpg/,".jpg")}; 1')
Run Code Online (Sandbox Code Playgroud)

这也没有任何替代品.我错过了什么吗?

Ben*_*son 5

我会通过编写一个带文件名并重命名的脚本来做到这一点:

#!/bin/sh

for FILE
do
    mv $FILE `basename $FILE jpg.jpg`.jpg
done
Run Code Online (Sandbox Code Playgroud)

该脚本很容易通过xargs.

如果你想将它粉碎到一个命令行,你可以做到,但它通常不值得麻烦.

编辑:如果我必须在一个命令行上执行它,我可能会使用不同的技巧xargs:使用sed将输出find转换为shell脚本:

find . -iname '*jpg.jpg' | sed -e 's/\(.*\)jpg\.jpg$/mv & \1.jpg/' | sh
Run Code Online (Sandbox Code Playgroud)

xargs能够分叉更少孩子的优势因mv无论如何都需要反复运行而失败.如果你真的需要这个优势,你需要一个类似我的第一个选项的解决方案,但编码类似的东西perl可以执行多个rename()调用,而不会忘记任何mv.