If using GNU mv
, you should rather do:
find . -type f -exec mv -t . {} +
With other mv
s:
find . -type f -exec sh -c 'exec mv "$@" .' sh {} +
You should never embed {}
in the sh
code. That's a command injection vulnerability as the names of the files are interpreted as shell code (try with a file called `reboot`
for instance).
Good point for quoting the command substitution, but because you used the archaic form (`...`
as opposed to $(...)
), you'd need to escape the inner double quotes or it won't work in sh
implementations based on the Bourne shell or AT&T ksh (where "`basename "foo bar"`"
would actually be treated as "`basename "
(with an unmatched `
which is accepted in those shells) concatenated with foo
and then bar"`"
).
Also, when you do:
mv foo/bar bar
If bar
actually existed and was a directory, that would actually be a mv foo/bar bar/bar
. mv -t . foo/bar
or mv foo/bar .
don't have that issue.
Now, to store those several arguments (-exec
, sh
, -c
, exec mv "$@" .
, sh
, {}
, +
) into a variable, you'd need an array variable. Shells supporting arrays are (t)csh
, ksh
, bash
, zsh
, rc
, es
, yash
, fish
.
And to be able to use that variable as just $FLATTEN
(as opposed to "${FLATTEN[@]}"
in ksh/bash/yash or $FLATTEN:q
in (t)csh
), you'd need a shell with a sane array implementation: rc
, es
or fish
. Also zsh
here as it happens none of those arguments is empty.
In rc
/es
/zsh
:
FLATTEN=(-exec sh -c 'exec mv "$@" .' sh '{}' +)
In fish
:
set FLATTEN -exec sh -c 'exec mv "$@" .' sh '{}' +
Then you can use:
find . -type f $FLATTEN