Search code examples
shellcommand-linezshxargs

How can I get xargs to do something with the input, then do another thing?


I'm in zsh.

I'd like to do something like:

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

Of course this cats all the slides, then appends a single "---" at the end instead of after each slide.

Is there an xargs way of doing this? Can I replace cat && echo "---" with some inline function or do block?


Very strangely, when I create a file cat---.sh with the contents

cat $1
echo ---

and run

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

it only executes for the first result of find.
Replace cat---.sh with cat and it runs on both files.


Solution

  • There's no need to use xargs at all here. Following is a properly paranoid approach (robust against files with spaces, files with newlines, files with literal backslashes in their names, etc):

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

    However -- you don't even need that either: find can do all the work itself, both printing the separator and calling cat!

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