问题
How can I combine the following two commands:
find . -print0 | grep -z pattern | tr '\0' '\n'
find . -print0 | grep -z pattern | xargs -0 my_command
into a single pipeline? If I don't need NUL separators then I can do:
find . | grep pattern | tee /dev/tty | xargs my_command
I want to avoid using a temporary file like this:
find . -print0 | grep -z pattern > tempfile
cat tempfile | tr '\0' '\n'
cat tempfile | xargs -0 my_command
rm tempfile
This question is a follow-up to these answers:
1) Using /dev/tty to display intermediate pipeline results:
https://unix.stackexchange.com/a/178754/8207082
2) Using a NUL-separated list of files:
https://stackoverflow.com/a/143172/8207082
Edited to use my_command
instead of command
.
Follow-up question:
Makefile rule that writes to /dev/tty inside a subshell?
回答1:
You can just change the tee to point to proc sub, then do the exact same thing in there.
find . -print0 | grep -z pattern | tee >(tr '\0' '\n' > /dev/tty) | xargs -0 command
The only issue with using tee this way, is that if the xargs command also prints to screen, then it is possible for all the output to get jumbled since both the pipe and process sub are asynchronous.
回答2:
One of the possibilities:
find . -print0 | grep -z pattern | { exec {fd}> >(tr '\0' '\n' >/dev/tty); tee "/dev/fd/$fd"; } | xargs -0 command
Where we create a temporary file descriptor fd
with exec
on fly which is connected to tr
's stdin via standard process substitution. tee
passes everything to stdout (ending on xargs
), and a duplicate to a tr
subprocess that outputs to /dev/tty
.
回答3:
It's possible to execute multiple commands with xargs like so:
find . -print0 | grep -z pattern | xargs -0 -I% sh -c 'echo "%"; command "%"'
Source:
https://stackoverflow.com/a/6958957/8207082
Per discussion, the above is unsafe, this is much better:
find . -print0 | grep -z pattern | xargs -0 -n 1 sh -c 'echo "$1"; my_command "$1"' _
来源:https://stackoverflow.com/questions/44730184/how-can-i-display-intermediate-pipeline-results-for-nul-separated-data