Como encontrar e copiar arquivos para um único diretório recursivamente no Linux?

Publicado 8 de setembro de 2024

Problema: Localizar e Copiar Arquivos entre Diretórios no Linux

Encontrar arquivos específicos em vários diretórios no Linux pode ser difícil. Copiar esses arquivos para um local único adiciona complexidade, especialmente com estruturas de pastas aninhadas.

A Solução Linux: Usando os Comandos Find e Copy

Usando o Comando 'find'

O comando 'find' no Linux ajuda a localizar arquivos e diretórios. Sua sintaxe básica é:

find [caminho] [opções] [expressão]

Onde:

  • [caminho] é o diretório para pesquisar
  • [opções] alteram o comportamento da pesquisa
  • [expressão] define os critérios de busca

Você pode pesquisar arquivos com base em:

  • Nome: Use '-name' com o padrão do nome do arquivo
  • Tipo: Use '-type' com 'f' para arquivos ou 'd' para diretórios
  • Tamanho: Use '-size' com o tamanho do arquivo
  • Tempo de modificação: Use '-mtime' com o número de dias

Por exemplo, para encontrar todos os arquivos .txt no diretório atual e seus subdiretórios:

find . -name "*.txt"

Dica: Excluir Diretórios da Pesquisa

Para excluir diretórios específicos da sua pesquisa, use as opções '-not' e '-path'. Por exemplo, para encontrar todos os arquivos .txt, mas excluir o diretório 'temp':

find . -name "*.txt" -not -path "./temp/*"

Combinando 'find' com 'cp' para Copiar

Encadear comandos permite usar a saída de um comando como entrada para outro. Combinando 'find' com 'cp', você pode localizar e copiar arquivos em uma única etapa.

Para usar 'find' e 'cp' juntos, use a opção '-exec' com 'find':

find [caminho] [critérios] -exec cp {} [destino] \;

Por exemplo, para encontrar todos os arquivos .jpg e copiá-los para uma pasta 'imagens':

find . -name "*.jpg" -exec cp {} ~/imagens \;

Este comando procura por arquivos .jpg no diretório atual e seus subdiretórios, e então copia cada arquivo para a pasta 'imagens' no diretório home.

Guia Passo a Passo para Encontrar e Copiar Arquivos Recursivamente

Configurando os Parâmetros de Pesquisa

Para iniciar a pesquisa de arquivos, defina o diretório de pesquisa. Pode ser um caminho específico ou o diretório atual ('.').

Para pesquisar no diretório /home/usuario/documentos:

find /home/usuario/documentos

Em seguida, defina os critérios de correspondência de arquivos. Critérios comuns incluem:

  • Nome: Use '-name' com o padrão do nome do arquivo entre aspas
  • Tipo: Use '-type' com 'f' para arquivos ou 'd' para diretórios
  • Tamanho: Use '-size' com '+' para maior que ou '-' para menor que, seguido pelo tamanho ('c' para bytes, 'k' para kilobytes, 'M' para megabytes)

Para encontrar todos os arquivos PDF maiores que 1MB:

find /home/usuario/documentos -name "*.pdf" -type f -size +1M

Executando a Operação de Cópia

Para copiar os arquivos encontrados pelo comando 'find', use a opção '-exec' com o comando 'cp'. A estrutura básica é:

find [diretório_de_pesquisa] [critérios] -exec cp {} [diretório_de_destino] \;

'{}' representa cada arquivo encontrado pelo 'find'.

Para copiar todos os arquivos .jpg de /home/usuario/imagens para /backup/imagens mantendo a estrutura original do diretório, use:

find /home/usuario/imagens -name "*.jpg" -exec cp --parents {} /backup/imagens \;

A opção '--parents' com 'cp' mantém a estrutura do diretório. Isso ajuda a organizar os arquivos e evitar conflitos de nomes no diretório de destino.

Dica: Use '-print0' para Nomes de Arquivos com Espaços

Se seus nomes de arquivos podem ter espaços, use a opção '-print0' com 'find' e a opção '-0' com 'xargs':

find /home/usuario/imagens -name "*.jpg" -print0 | xargs -0 cp -t /backup/imagens

Isso lida corretamente com nomes de arquivos que contêm espaços.

Exemplo: Excluir Diretórios Específicos

Para excluir certos diretórios da sua pesquisa, use as opções '-not' e '-path':

find /home/usuario/documentos -name "*.txt" -not -path "*/tmp/*" -exec cp {} /backup/textos \;

Este comando copia todos os arquivos .txt de /home/usuario/documentos para /backup/textos, excluindo quaisquer arquivos em diretórios chamados 'tmp'.

Considerações Adicionais para Operações com Arquivos

Lidando com Permissões e Propriedade

Ao copiar arquivos, você pode enfrentar problemas de permissão. Isso pode ocorrer se você não tiver acesso para ler os arquivos de origem ou escrever no diretório de destino. Para evitar esses problemas, pode ser necessário executar o comando de cópia com privilégios sudo.

Para manter os atributos originais do arquivo, use a opção '-p' com o comando 'cp'. Aqui está um exemplo:

find /diretorio/origem -name "*.txt" -exec cp -p {} /diretorio/destino \;

Este comando copia todos os arquivos .txt do diretório de origem para o diretório de destino, mantendo suas permissões e propriedade originais.

Para mais controle sobre as permissões, use a opção '--preserve' com 'cp':

find /diretorio/origem -name "*.txt" -exec cp --preserve=mode,ownership,timestamps {} /diretorio/destino \;

Este comando mantém o modo do arquivo, propriedade e carimbos de data/hora dos arquivos originais.

Lidando com Nomes de Arquivos Duplicados

Ao copiar arquivos para um novo local, você pode encontrar arquivos com os mesmos nomes. Por padrão, o comando 'cp' substituirá os arquivos existentes no diretório de destino.

Para evitar a substituição de arquivos, use a opção '-n' com 'cp':

find /diretorio/origem -name "*.txt" -exec cp -n {} /diretorio/destino \;

Este comando não substituirá os arquivos existentes no diretório de destino.

Outro método é adicionar um sufixo aos arquivos copiados. Use a opção '--backup' com 'cp':

find /diretorio/origem -name "*.txt" -exec cp --backup=numbered {} /diretorio/destino \;

Este comando adiciona um número ao final de quaisquer nomes de arquivos duplicados no diretório de destino.

Você também pode usar o comando 'rsync' em vez de 'cp' para ter mais controle sobre a cópia de arquivos:

find /diretorio/origem -name "*.txt" -print0 | rsync -av --files-from=- --from0 /diretorio/origem /diretorio/destino

Este comando usa 'rsync' para copiar arquivos, que pode lidar com duplicatas de forma mais flexível e fornece opções para atualizar apenas arquivos alterados.

Dica: Use 'cpio' para Operações de Cópia Complexas

Para operações de cópia complexas, considere usar o comando 'cpio':

find /diretorio/origem -name "*.txt" -print0 | cpio -pmd0 /diretorio/destino

Este comando usa 'cpio' para copiar arquivos, que pode lidar com grandes números de arquivos de forma mais eficiente do que 'cp'.