Search code examples
shellxargsash

Storing 'find -print0' in intermediate variable without losing nul char


I have the following sequence of commands to lint JSON files in a directory:

npm install --global --no-save jsonlint-cli
FILES="$(find . -name '*.json' -type f -print)"
echo -e "Discovered JSON files:\n$FILES"
echo "$FILES" | tr '\n' ' ' | xargs jsonlint-cli

I fully realize this is a NO-NO because it does not use the -print0 | xargs -0 pattern.

However, I would like to retain the ability to echo the discovered files but also invoke find and jsonlint-cli only once.

This is made difficult by the fact that ash can't store \0 in a variable. So this will not work:

FILES="$(find . -name '*.json' -type f -print0)"
echo -e "Discovered JSON files:\n$FILES" | tr '\0' '\n'  # No effect, '\0' already gone
echo "$FILES" | xargs -0 jsonlint-cli

How can I use -print0 | xargs -0 will still maintaining the current behavior of echoing the discovered files to stdout?

The shell in this case is ash (inside a node:alpine Docker container).


Solution

  • Can't see anything that keeps you from doing it like this:

    echo 'Discovered JSON files:'
    find . -name '*.json' -type f -print -exec jsonlint-cli {} +
    

    Note that if you have so many files that find needs to split them into sets, this won't work as you expected.