如何让xargs对输入做一些事情,然后做另一件事?

时间:2015-08-21 15:32:02

标签: shell command-line zsh xargs

我在zsh。

我想做点什么:

find . -iname *.md | xargs cat && echo "---" > all_slides_with_separators_in_between.md

当然这只猫是所有的幻灯片,然后在末尾添加一个“---”而不是每张幻灯片。

是否有xargs方式这样做?我可以使用内联函数或cat && echo "---"块替换do吗?

<小时/> 非常奇怪的是,当我使用内容

创建文件cat---.sh
cat $1
echo ---

并运行

find . -iname *.md | xargs ./cat---.sh

它仅针对查找的第一个结果执行 用cat替换cat---sh,它在两个文件上运行。

5 个答案:

答案 0 :(得分:3)

这里根本不需要使用xargs。以下是一种适当的偏执方法(针对带空格的文件,带换行符的文件,名称中带有字形反斜杠的文件等):

while IFS= read -r -d '' filename; do
  printf '---\n'
  cat -- "$filename"
done < <(find . -iname '*.md' -print0) >all_slides_with_separators.md

但是 - 您甚至不需要:find可以自己完成所有工作,同时打印分隔符调用cat

find . -iname '*.md' -printf '---\n' -exec cat -- '{}' ';' >all_slides_with_separators.md

答案 1 :(得分:2)

常见的使用模式是xargs sh -c 'command; another' _,其中引号中的整个shell脚本都可以访问命令行参数。下划线是因为sh -c的第一个参数将被分配到$0(您经常会在-sh列表中看到ps)。

find . -iname '*.md' |
xargs sh -c 'for x; do
  cat "$x" && echo "---"
done' _ > all_slides_with_separators_in_between.md

正如评论中所述,您应该调查find -print0以及GNU xargs -0中相应的find选项(如果您没有,可以安装它)。

答案 2 :(得分:1)

你可以这样做,但在某些情况下可能不安全(见评论):

find . -iname '*.md' | xargs -I % sh -c '{ cat %; echo "----"; }' > output.txt

答案 3 :(得分:1)

find中您很少需要zsh;它的通道设施几乎覆盖了find的所有用例。

for f in (#i)**/*.md; do
    cat $f
    print -- "---"
done > all_slides.md

以不区分大小写的方式查找与*.md匹配的每个文件的当前目录层次结构。

为了提高效率,请将cat $f替换为< $f; zsh本身将读取文件并将其内容写入标准输出。

答案 4 :(得分:0)

使用GNU Parallel看起来像这样:

parallel cat {}\; print -- --- ::: **/*.md