Here's a command that works fine:
echo Blah: `stat -c %a .`
Is it possible to get find -exec
to execute this same thing for every file found, with {}
in place of .
?
Server Fault is a question and answer site for system and network administrators. It only takes a minute to sign up.
Sign up to join this communityHere's a command that works fine:
echo Blah: `stat -c %a .`
Is it possible to get find -exec
to execute this same thing for every file found, with {}
in place of .
?
The best way to do that is to use positional parameters. And $()
is preferred for command substitution ove backticks because it's more readable (isn't confused with single quotes) and can be easily nested without having to do a lot of escaping.
find . -exec bash -c 'echo Blah: $(stat -c %a "$@")' _ {} \;
The underscore is a placeholder for $0
.
What for?
find ... -printf 'Blah: %m\n'
Or use bash -c
if you really have to:
find . -exec bash -c 'echo Blah: `stat -c %a {}`' \;
The only way to use them (AFAIK) is to place them in a bash script file and use the script in -exec. Same thing with $()
Don't forget xargs
!
Your example would invoke a new shell process for each file found.
I would prefer this:
find ... | xargs stat -c "Blah: %a"
find
outputs a list of everything found, xargs
reads a list of arguments on stdin
and executes its parameter with those arguments on the command line, building as long a command line as possible.
It works because stat
, as most other proper commands/programs do, take any number of parameters. (compare ls
, rm
and echo
for instance)
If you think it's absolutely neccessary to launch a new process for each file, use xargs -n 1
to only pass 1
parameter to each command.
That way you can mimick the inefficient methods like this:
find ... | xargs -n 1 stat -c "Blah: %a"
(Try it on a big filesystem on a slow computer and time the differences!)
find
is even executed and the result is used as a static parameter for find. – Sven Feb 8 '11 at 13:43