修改xargs中的替换字符串

bet*_*ido 48 bash xargs

当我xargs有时使用时,我不需要显式使用替换字符串:

find . -name "*.txt" | xargs rm -rf
Run Code Online (Sandbox Code Playgroud)

在其他情况下,我想指定替换字符串,以便执行以下操作:

find . -name "*.txt" | xargs -I '{}' mv '{}' /foo/'{}'.bar
Run Code Online (Sandbox Code Playgroud)

上一个命令会将当前目录下的所有文本文件移入/foo,并将扩展名附加bar到所有文件.

如果不是将一些文本附加到替换字符串,我想修改该字符串,以便我可以在文件的名称和扩展名之间插入一些文本,我该怎么做?例如,假设我想要像上一个示例中那样做,但是文件应该重命名/移动<name>.txt/foo/<name>.bar.txt(而不是/foo/<name>.txt.bar).

更新:我设法找到一个解决方案:

find . -name "*.txt" | xargs -I{} \
    sh -c 'base=$(basename $1) ; name=${base%.*} ; ext=${base##*.} ; \
           mv "$1" "foo/${name}.bar.${ext}"' -- {}
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有更短/更好的解决方案.

fai*_*dox 34

以下命令使用xargs构造move命令,替换第二次出现的'.' 使用'.bar.',然后使用bash执行命令,在mac OSX上工作.

ls *.txt | xargs -I {} echo mv {} foo/{} | sed 's/\./.bar./2' | bash
Run Code Online (Sandbox Code Playgroud)


San*_*rix 22

可以在一次通过(在GNU中测试)中执行此操作,避免使用临时变量赋值

find . -name "*.txt" | xargs -I{} sh -c 'mv "$1" "foo/$(basename ${1%.*}).new.${1##*.}"' -- {}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你使用替换字符串作为shell的位置参数的方式,以便您可以执行替换和扩展.很酷. (3认同)

gle*_*man 17

在这种情况下,while循环会更具可读性:

find . -name "*.txt" | while IFS= read -r pathname; do
    base=$(basename "$pathname"); name=${base%.*}; ext=${base##*.}
    mv "$pathname" "foo/${name}.bar.${ext}"
done
Run Code Online (Sandbox Code Playgroud)

请注意,您可能会在不同的子目录中找到具有相同名称的文件.是否可以覆盖重复的副本mv

  • 请注意,如果您尝试使用`--max-procs`并行化xargs,则此(串行)方法将不起作用. (3认同)
  • 要处理其中包含换行符的文件名,请使用:`find.-name"*.txt"-print0 | 同时读取-r -d''路径名; 做......` (2认同)

Ole*_*nge 11

如果你安装了GNU Parallel http://www.gnu.org/software/parallel/,你可以这样做:

find . -name "*.txt" | parallel 'ext="{/}" ; mv -- {} foo/{/.}.bar.${ext##*.}'
Run Code Online (Sandbox Code Playgroud)

观看GNU Parallel的介绍视频以了解更多信息:https: //www.youtube.com/playlist?list = PL284C9FF2488BC6D1

  • @MestreLion请不要推荐curl-pipe-to-shell反模式.什么是`pi.dk`?我为什么要信任该域名?`gnu.org`至少更值得信赖.但是这两个URL都没有使用TLS,更重要的是,没有人验证下载内容的加密签名.推荐的唯一解决方案是`apt-get`. (3认同)
  • 我还推荐GNU Parallel而不是`xargs`,它更强大,更灵活.至于它的安装,我强烈建议使用你的发行版的包管理器(例如`sudo apt-get install parallel`)或者并行推荐的安装程序(根据http://git.savannah.gnu.org/cgit/parallel). git/tree/README):`(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3)| bash` (2认同)
  • @blujay:这不是*我的建议,这是从官方文档***中获取的:http://www.gnu.org/software/parallel/parallel_tutorial.html#Prerequisites.虽然我同意这不如使用你的发行版的软件包管理器那么好,但它比简单的`wget ... && chmod + x更好*. (2认同)
  • @MestreLion很遗憾它在Parallel网站上,你不应该进一步传播它.它并不比'wget ...'更好,因为它[因为很多原因而危险](https://www.seancassidy.me/dont-pipe-to-your-shell.html).这无异于告诉Windows用户从一个随机网站运行`exe`而不扫描病毒.拒绝吧. (2认同)