Se estiver usando o GNU mv
, você deve fazer:
find . -type f -exec mv -t . {} +
Com outros mv
s:
find . -type f -exec sh -c 'exec mv "$@" .' sh {} +
Você nunca deve incorporar {}
no código sh
. Essa é uma vulnerabilidade de injeção de comando, pois os nomes dos arquivos são interpretados como códigos de shell (tente com um arquivo chamado 'reboot'
, por exemplo).
Bom ponto para citar a substituição de comando, mas como você usou o formulário arcaico ( '...'
em oposição a $(...)
), você precisaria escapar das aspas duplas internas ou ele não funcionará em sh
implementações baseadas no shell Bourne ou AT & T ksh (onde "'basename "foo bar"'"
seria realmente tratado como "'basename "
(com um '
incomparável que é aceito em essas conchas) concatenadas com foo
e, em seguida, bar"'"
).
Além disso, quando você faz:
mv foo/bar bar
Se bar
existisse e fosse um diretório, na verdade seria um mv foo/bar bar/bar
. mv -t . foo/bar
ou mv foo/bar .
não têm esse problema.
Agora, para armazenar esses vários argumentos ( -exec
, sh
, -c
, exec mv "$@" .
, sh
, {}
, +
) em uma variável, você precisaria de uma variável de matriz . Shells que suportam matrizes são (t)csh
, ksh
, bash
, zsh
, rc
, es
, yash
, fish
.
E para poder usar essa variável como apenas $FLATTEN
(em oposição a "${FLATTEN[@]}"
em ksh / bash / yash ou $FLATTEN:q
em (t)csh
), você precisaria de um shell com uma implementação de matriz sã : rc
, es
ou fish
. Também zsh
aqui, como acontece, nenhum desses argumentos está vazio.
Em rc
/ es
/ zsh
:
FLATTEN=(-exec sh -c 'exec mv "$@" .' sh '{}' +)
Em fish
:
set FLATTEN -exec sh -c 'exec mv "$@" .' sh '{}' +
Então você pode usar:
find . -type f $FLATTEN