我怎样才能让 xargs 对输入做一些事情,然后再做另一件事?
How can I get xargs to do something with the input, then do another thing?
我在 zsh。
我想做这样的事情:
find . -iname *.md | xargs cat && echo "---" > all_slides_with_separators_in_between.md
当然,这会覆盖所有幻灯片,然后在末尾而不是在每张幻灯片之后附加一个“---”。
有 xargs 方法吗?我可以用一些内联函数或 do
块替换 cat && echo "---"
吗?
很奇怪,当我创建一个文件 cat---.sh
内容为
cat
echo ---
和运行
find . -iname *.md | xargs ./cat---.sh
它只对查找的第一个结果执行。
将 cat---.sh 替换为 cat,并且它在两个文件中都为 运行s。
常见的使用模式是 xargs sh -c 'command; another' _
,其中引号中的整个 shell 脚本都可以访问命令行参数。下划线是因为 sh -c
的第一个参数将分配给 [=13=]
(您经常会在 ps
列表中看到 -sh
)。
find . -iname '*.md' |
xargs sh -c 'for x; do
cat "$x" && echo "---"
done' _ > all_slides_with_separators_in_between.md
如评论中所述,您可能应该调查 find -print0
和 GNU find
中相应的 xargs -0
选项(如果没有,则可以安装它)。
这里完全没有必要使用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
你可以这样做,但在某些情况下它可能不安全(见评论):
find . -iname '*.md' | xargs -I % sh -c '{ cat %; echo "----"; }' > output.txt
您在 zsh
中很少需要 find
;它的 globbing 设施几乎涵盖了 find
.
的所有用例
for f in (#i)**/*.md; do
cat $f
print -- "---"
done > all_slides.md
这会以不区分大小写的方式在当前目录层次结构中查找与 *.md
匹配的每个文件。
为了提高效率,将cat $f
替换为< $f
; zsh
本身将读取文件并将其内容写入标准输出。
使用 GNU Parallel 看起来像这样:
parallel cat {}\; print -- --- ::: **/*.md
我在 zsh。
我想做这样的事情:
find . -iname *.md | xargs cat && echo "---" > all_slides_with_separators_in_between.md
当然,这会覆盖所有幻灯片,然后在末尾而不是在每张幻灯片之后附加一个“---”。
有 xargs 方法吗?我可以用一些内联函数或 do
块替换 cat && echo "---"
吗?
很奇怪,当我创建一个文件
cat---.sh
内容为
cat
echo ---
和运行
find . -iname *.md | xargs ./cat---.sh
它只对查找的第一个结果执行。
将 cat---.sh 替换为 cat,并且它在两个文件中都为 运行s。
常见的使用模式是 xargs sh -c 'command; another' _
,其中引号中的整个 shell 脚本都可以访问命令行参数。下划线是因为 sh -c
的第一个参数将分配给 [=13=]
(您经常会在 ps
列表中看到 -sh
)。
find . -iname '*.md' |
xargs sh -c 'for x; do
cat "$x" && echo "---"
done' _ > all_slides_with_separators_in_between.md
如评论中所述,您可能应该调查 find -print0
和 GNU find
中相应的 xargs -0
选项(如果没有,则可以安装它)。
这里完全没有必要使用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
你可以这样做,但在某些情况下它可能不安全(见评论):
find . -iname '*.md' | xargs -I % sh -c '{ cat %; echo "----"; }' > output.txt
您在 zsh
中很少需要 find
;它的 globbing 设施几乎涵盖了 find
.
for f in (#i)**/*.md; do
cat $f
print -- "---"
done > all_slides.md
这会以不区分大小写的方式在当前目录层次结构中查找与 *.md
匹配的每个文件。
为了提高效率,将cat $f
替换为< $f
; zsh
本身将读取文件并将其内容写入标准输出。
使用 GNU Parallel 看起来像这样:
parallel cat {}\; print -- --- ::: **/*.md