I’m using fd
, an alternative to the Unix native find
, to find a list of files and copy them to a different location, using xargs
. On Unix, we use cp
to copy the files, but the command is silent.
I don’t know which files cp
will copy. Maybe I could use echo
to log the files?
How can I pass multiple shell commands to xargs
?
Previous command:
fd --changed-within 1hour -0 | xargs -I cp {} /new/location/
fd -0 --changed-within
: find all files changed within a time frame, separate results by null character|
: pipe previous command asstdin
to the next commandxargs -I cp {} /new/location/
: takes the input from previous command (fd
) and usescp
to copy the files;{}
is a placeholder
What does not work:
fd --changed-within 1hour -0 | xargs -I cp {} /new/location/ | xargs -I echo {}
What does work:
fd --changed-within 1hour -0 | xargs -0 sh -c \
'for arg do echo "$arg"; cp "$arg" /new/location/; done' _
xargs -0
: use null as separating character (useful for files that contain whitespace)sh -c
: read commands from next string'for arg do echo "$arg"; cp "$arg" /new/location/; done' _
: loop over each input and first useecho
to log, thencp
to new location_
is a placeholder for$0
, such that other data values added byxargs
become$1
and onward, which happens to be the default set of values afor
loop iterates over.
This is shell magic to me!
I found the solution on StackOverflow, where you can also find a more detailed explanation.