【发布时间】:2012-06-03 22:06:57
【问题描述】:
当我使用xargs 时,有时我不需要显式使用替换字符串:
find . -name "*.txt" | xargs rm -rf
在其他情况下,我想指定替换字符串以执行以下操作:
find . -name "*.txt" | xargs -I '{}' mv '{}' /foo/'{}'.bar
前面的命令会将当前目录下的所有文本文件移动到/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}"' -- {}
但我想知道是否有更短/更好的解决方案。
【问题讨论】:
-
不,除了我会使用更多的引用
mv "$1" "foo/${name}.bar.${ext}"而你可以这样做basename像这样:base=${1##*/}。您应该发布您的解决方案作为答案并接受它。 -
@DennisWilliamson 感谢您的评论!我再等一会儿,看看有没有人想出什么花哨的东西,否则我会自己回答问题。
-
我认为如果你的文件名是最后一行,你不需要 -I{} 或 {} 在命令行中。 (请注意,xargs 的真正目的是进行分组,因此如果您不希望在 1 个 xargs 参数调用结束时需要多个东西,则需要“-l 1”(或 -L 1 用于某些版本的 xargs)。 -I{} 意味着 -l 1,这就是为什么它也适用于此。)
-
sh -c对我来说是关键!谢谢!否则我在echo {}|sed '...'中的 cut/sed 命令未执行