find . -name '*.tar' -exec tar xf {} -C "$(dirname {})" \;
find . -name '*.tar' -exec sh -c 'tar xf "$1" -C "$(dirname "$1")"' _ {} \;
Bash evaluates any command substitutions before the command they
feature in is executed. In this case, the command is find
.
This means that $(dirname {})
will run
before find
runs, and not
while find
runs.
To run shell code for each file, we can write a tiny script and
inline it with sh -c
. We add _
as a dummy
argument that becomes $0
, and a filename argument that
becomes $1
in the inlined script:
$ sh -c 'echo "$1 is in $(dirname "$1")"' _ "mydir/myfile"
mydir/myfile is in mydir
This command can be executed by find -exec
, with
{}
as the filename argument. It executes shell which
interprets the inlined script once for each file. Note that the inlined
script is single quoted, again to ensure that the expansion does not
happen prematurely .
If you don't care (or if you prefer) that it's only expanded once, like when dynamically selecting the executable to be used by all invocations, you can ignore this message.
ShellCheck is a static analysis tool for shell scripts. This page is part of its documentation.