-exec
only takes one command (with optional arguments) and you can't use any bash operators in it.
So you need to wrap it in a bash -c '...'
block, which executes everything between '...'
in a new bash shell.
find . -type f -name "test" -exec bash -c 'tail -n 2 /source.txt >> "$1"' bash {} \;
Note: Everything after '...'
is passed as regular arguments, except they start at $0 instead of $1. So the bash
after '
is used as a placeholder to match how you would expect arguments and error processing to work in a regular shell, i.e. $1 is the first argument and errors generally start with bash
or something meaningful
If execution time is an issue, consider doing something like export variable="$(tail -n 2 /source.txt)"
and using "$variable"
in the -exec
. This will also always write the same thing, unlike using tail
in -exec
, which could change if the file changes. Alternatively, you can use something like -exec ... +
and pair it with tee
to write to many files at once.