Como você pode mover (ou copiar) todos os arquivos de um determinado tipo para um diretório no Unix?

22

Ainda não estou muito familiarizado com todos os truques grep/find/awk/xargs.

Eu tenho alguns arquivos que correspondem a um padrão específico, digamos *.xxx. Esses arquivos estão em locais aleatórios em um determinado diretório. Como posso encontrar todos esses arquivos e movê-los para uma pasta no meu diretório pessoal no Unix (que talvez ainda não exista)?

qodeninja
fonte
4
Você precisa tomar cuidado ao falar sobre "tipo de arquivo". Em ambientes unixy, o exemplo ".xxx" nem sequer é uma extensão no sentido do Windows. ".xxx" apenas constitui um sufixo do nome do arquivo. "Tipo de arquivo" é mais uma das poucas categorias: arquivo normal, arquivo de dispositivo, link simbólico, diretório, pipe nomeado, soquete da família Unix, talvez algumas outras.
11558 Bruce Ediger
1
Veja também: unix.stackexchange.com/questions/7027/…
jasonwryan
@BruceEdiger graças Eu acho que eu realmente queria dizer "padrão de ficheiros"
qodeninja

Respostas:

22
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
Kevin
fonte
1
Eu usariamv -i -t ~/dst {} +
enzotib
17

Se você deseja mover todos os arquivos dentro de uma hierarquia de diretórios para um único diretório de destino, no bash ≥4 (coloque shopt -s globstarno seu ~/.bashrc) ou no zsh:

mkdir ~/new-directory
mv -i **/*.xxx ~/new-directory

Em outras conchas:

mkdir ~/new-directory
find . -name '*.xxx' -exec mv -i {} ~/new-directory \;

Como ler este findcomando:

  • .: percorre o diretório atual
  • -name '*.xxx': agir em arquivos cujo nome corresponda a esse padrão
  • -exec … \;: execute este comando em cada arquivo, substituindo {}pelo caminho para o arquivo

Existe um comando mais complexo findque é mais rápido se você tiver muitos arquivos, pois não precisará chamar um mvprocesso separado para cada arquivo:

find . -name '*.xxx' -exec sh -c 'mv -i "$@" "$0"' ~/new-directory {} +

O +no final diz findpara chamar o comando em vários arquivos por vez. Como findsó podemos colocar os nomes dos arquivos no final da linha de comando e mvprecisamos ter o diretório de destino por último, usamos um shell intermediário para reorganizar os argumentos ( "$0"é o primeiro argumento para o shell ~/new-directorye "$@"os argumentos subsequentes provenientes de findexpansão de {}).

Gilles 'SO- parar de ser mau'
fonte
4

Se você deseja replicar a estrutura de diretórios dos arquivos de origem correspondentes para o novo diretório de destino, pode usar a opção --parents do GNU cp :

mkdir /path/to/target_dir
cd source_dir
find . -name '*.xxx' -exec cp -iv --parents -t /path/to/target_dir {} +
frielp
fonte
3

você pode usar achado sem -exec‍bem:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
Ken Zein
fonte
1
Observe, porém, que find -execé muito mais seguro; o acima falhará em nomes de arquivos que contenham espaço em branco, por exemplo.
dhag