Estou tentando executar um comando semelhante ao abaixo em um script bash. Ele deve procurar por todas as subpastas $sourcedir
e copiar todos os arquivos de um determinado tipo para o nível raiz de $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
Isso parece bem próximo, exceto que {}
não está sendo repassado $2
para-exec sh -c ...
Eu gostaria de fazer isso o mais próximo possível da "maneira correta", com tolerância a caracteres especiais em nomes de arquivos (especificamente aspas simples).
Editar: vejo pessoas sugerindo o uso xargs
ou encadeamento de argumentos. Fiquei com a impressão de que isso não é aceitável para um número limitado de argumentos. Se eu tiver, por exemplo, milhares de arquivos .jpg que estou tentando copiar de vários diretórios da galeria para um diretório gigante de apresentações de slides, as soluções que encadearão argumentos ainda funcionarão?
Edit 2: Meu problema era que faltava um _
antes da minha primeira opção para sh no -exec
comando. Para quem estiver curioso sobre como fazer o comando find funcionar, adicione _
oe tudo ficará bem:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
Aceitei uma resposta abaixo, porém, porque ela realiza a mesma tarefa, mas é mais eficiente e elegante.
xargs
foi criado, para lidar automaticamente com grandes quantidades de argumentos em comandos regulares que tinham limites. Além disso, a maioria dos limites máximos de argumentos foi amplamente aprimorada para os utilitários GNU padrão. Você também verá um benefício no desempenho, evitando todos os garfos do processo, que em milhares de arquivos são relevantes.