使用Xargs和SED或尴尬的Backticks或$()



假设我想更改一些以 jpg.jpg结尾的文件名以仅以 .jpg结束(bash),我想通过将find的输出输出到 xargs

使用sed

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

但是,这不会在mv的目标文件中替换jpg.jpg

使用awk

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

这都不替代。我错过了什么吗?

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

#!/bin/sh
for FILE
do
    mv $FILE `basename $FILE jpg.jpg`.jpg
done

该脚本很容易通过xargs来调用。

如果要将其砸在单个命令行上,则可以做到,但通常不值得麻烦。

编辑:如果我必须在一个命令行上进行操作,我可能会在没有xargs的情况下使用其他技巧:使用sedfind的输出转换为shell脚本:

find . -iname '*jpg.jpg' | sed -e 's/(.*)jpg.jpg$/mv & 1.jpg/' | sh

xargs能够少量分叉的优势被反复运行mv的需要打败。如果您确实需要优势,则需要像我的第一个选项这样的解决方案,但在诸如perl之类的内容中进行了编码,该解决方案可以执行多个rename()呼叫而无需判断任何mv

如果您的系统上有rename命令,则以下命令应起作用:

rename 's/(.*)jpg.jpg/$1.jpg/g' *jpg.jpg

$(...)在运行XARGS之前通过Bash评估CC_20,因此Xargs只是看到该表达式的输出,因为它当前是MV的第二个参数。

因此,它等效于:

... | xargs -I % mv % %

我将与GNU并行同行:

find . -iname '*jpg.jpg' | parallel mv {} {.}

{}被输入替换,{.}被输入减去最后扩展名代替。并行使用--dry-run,以查看将要做什么。

编辑 - 应处理file1jpg.jpg

根据保留案例的需求,可以通过参数扩展或使用GNU来完成:

参数扩展:

find . -iname '*jpg.jpg' | parallel v={}; mv '{}' '${v/jpg.jpg/.jpg}'    

与gnu sed:

find . -iname '*jpg.jpg' | parallel mv '{}' '$(echo {} | sed -r "s/jpg\.(jpg)$/.1/I")'

不需要xargsfind

for i in *jpg.jpg; do mv "$i" "$(echo $i | sed 's/jpg.jpg$/.jpg/')"; done

sedawk实际上并不需要:

for i in $(find . -type f -name "*jpg.jpg"); do mv "$i" "${i/%jpg.jpg/.jpg}"; done

这是另一种方法:

find . -type f -name "*jpg.jpg" -exec bash -c 'mv $0 ${0/%jpg.jpg/.jpg}' {} ;

相关内容

  • 没有找到相关文章

最新更新