Como copiar uma estrutura de diretório, mas apenas incluir determinados arquivos (usando arquivos do Windows lote)

StackOverflow https://stackoverflow.com/questions/472692

Pergunta

Como o título diz, como posso copiar recursivamente uma estrutura de diretório, mas apenas incluir alguns arquivos. Por exemplo, dada a seguinte estrutura de diretório:

folder1
  folder2
    folder3
      data.zip
      info.txt
      abc.xyz
    folder4
    folder5
      data.zip
      somefile.exe
      someotherfile.dll

Os arquivos data.zip e info.txt pode aparecer em todos os lugares na estrutura de diretórios. Como posso copiar a estrutura do diretório completo, mas apenas incluir arquivos chamados data.zip e info.txt (todos os outros arquivos deve ser ignorado)?

A estrutura de diretório resultante deve ficar assim:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
Foi útil?

Solução

Você não mencionou se ele tem que ser apenas lote, mas se você pode usar ROBOCOPY, tente o seguinte:

ROBOCOPY C:\Source C:\Destination data.zip info.txt /E

EDIT:. Mudou o parâmetro /S para /E para incluir pastas vazias

Outras dicas

Uma solução alternativa que copia um arquivo de cada vez e não requer ROBOCOPY:

@echo off
setlocal enabledelayedexpansion

set "SOURCE_DIR=C:\Source"
set "DEST_DIR=C:\Destination"
set FILENAMES_TO_COPY=data.zip info.txt

for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
    if exist "%%F" (
        set FILE_DIR=%%~dpF
        set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
        xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
    )
)

O externa para instrução gera qualquer combinação possível caminho de subdiretório no SOURCE_DIR e nome em FILENAMES_TO_COPY. Para cada xcopy arquivo existente é invocado. FILE_INTERMEDIATE_DIR detém caminho do subdiretório do arquivo dentro SOURCE_DIR que precisa ser criado em DEST_DIR.

tentar tubulação de saída de find (ie. O caminho do arquivo) em cpio

find . -type f -name '*.jpg' | cpio -p -d -v targetdir/

cheques cpio timestamp em arquivos de destino - por isso é seguro e rápido

.

remover -v para op mais rápido, uma vez que você se acostumar com isso.

Se PowerShell é uma opção, você pode fazer isso:

Copy-Item c:\sourcePath d:\destinationPath -filter data.zip -recurse

A principal desvantagem é que copia todas as pastas, mesmo que eles vão acabar sendo vazia porque nenhum arquivo correspondem ao filtro especificado. Então você pode acabar com uma árvore cheia de pastas vazias, além de poucas pastas que têm os arquivos que deseja.

Graças às respostas anteriores. :)

Este script chamado "r4k4copy.cmd":

@echo off
for %%p in (SOURCE_DIR DEST_DIR FILENAMES_TO_COPY) do set %%p=
cls
echo :: Copy Files Including Folder Tree
echo :: http://stackoverflow.com
rem     /questions/472692/how-to-copy
rem     -a-directory-structure-but-only
rem     -include-certain-files-using-windows
echo :: ReScripted by r4k4
echo.
if "%1"=="" goto :NoParam
if "%2"=="" goto :NoParam
if "%3"=="" goto :NoParam
setlocal enabledelayedexpansion
set SOURCE_DIR=%1
set DEST_DIR=%2
set FILENAMES_TO_COPY=%3
for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
if exist "%%F" (
set FILE_DIR=%%~dpF
set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
)
)
goto :eof
:NoParam
echo.
echo Syntax: %0 [Source_DIR] [Dest_DIR] [FileName]
echo Eg.   : %0 D:\Root E:\Root\Lev1\Lev2\Lev3 *.JPG
echo Means : Copy *.JPG from D:\Root to E:\Root\Lev1\Lev2\Lev3

Ele aceita variável de "Source", "Destino", e "nome do arquivo". Ele também só pode copiar tipo especificado de arquivos ou nomes de arquivos seletivos.

Qualquer melhoria é bem-vindo. :)

Com achado e cp apenas:

mkdir /tmp/targetdir
cd sourcedir
find . -type f -name '*.zip' -exec cp -p --parents {} /tmp/targetdir ";"
find . -type f -name '*.txt' -exec cp -p --parents {} /tmp/targetdir ";"

Semelhante a solução Paulius', mas os arquivos que você não se preocupam não são copiados em seguida, excluído:

@echo OFF

:: Replace c:\temp with the directory where folder1 resides.
cd c:\temp

:: You can make this more generic by passing in args for the source and destination folders.
for /f "usebackq" %%I in (`dir /b /s /a:-d folder1`) do @echo %%~nxI | find /V "data.zip" | find /v "info.txt" >> exclude_list.txt
xcopy folder1 copy_of_folder1 /EXCLUDE:exclude_list.txt /E /I

Isso é apenas dois comandos simples, mas eu não recomendo este, a menos que os arquivos que você não precisa de cópia são pequenos. Isso porque este irá copiar todos os arquivos e, em seguida, remover os arquivos que não são necessários na cópia.

xcopy /E /I folder1 copy_of_folder1
for /F "tokens=1 delims=" %i in ('dir /B /S /A:-D copy_of_files ^| find /V "info.txt" ^| find /V "data.zip"') do del /Q "%i"

Claro, o segundo comando é tipo de muito tempo, mas funciona!

Além disso, esta abordagem não exige que você baixar e instalar quaisquer ferramentas de terceiros (Windows 2000+ LOTE tem comandos suficientes para isso).

De acordo com outros sistemas Linux e UNIX, usando o comando tar iria fazer isso facilmente.

$ tar cvf /tmp/full-structure.tar *data.zip *info.txt

Então você CWD ao alvo e:

$ tar xvf /tmp/full-structure.tar 

Claro que você poderia canalizar a saída do primeiro tar na 2ª, mas vê-lo trabalhar em etapas é mais fácil de entender e explicar. Eu sinto falta do cd necessário / to / novo caminho / / no comando a seguir - Eu só não me lembro de como fazê-lo agora. Alguém pode adicioná-lo, eu espero.

$ tar cvf -  *data.zip *info.txt |  tar xvf - 

Tar (gnutar) está disponível no Windows também, mas eu provavelmente iria usar o método xcopy me nessa plataforma.

XCOPY /S folder1\data.zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

EDIT:. Se você quiser preservar as pastas vazias (que, na releitura seu post, você parece) o uso / E em vez de / S

Usando a interface de linha de comando WinRAR, você pode copiar os nomes de arquivo e / ou tipos de arquivos a um arquivo. Depois, você pode extrair esse arquivo para qualquer local que você gosta. Isso preserva a estrutura do arquivo original.

eu precisava para adicionar faltando arquivos de imagem do álbum para o meu celular sem ter que copiar novamente a música em si. Felizmente, o estrutura de diretórios foi o mesmo no meu computador e mobile

eu usei:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ Downloads \ music.rar = Arquivo a ser criado
  • X: \ música \ = A pasta que contém arquivos de música
  • folder.jpg = Matrícula eu queria copiar

Isto criou um arquivo com todos os arquivos folder.jpg nos subdiretórios apropriados.

Esta técnica pode ser usada para copiar tipos de arquivo também. Se os arquivos de todas tinham nomes diferentes, você pode optar por extrair todos os arquivos em um único diretório. parâmetros de linha de comando adicionais podem arquivar vários tipos de arquivo.

Mais informação nesta ligação muito útil http: // cects.com/using-the-winrar-command-line-tools-in-windows/

Para aqueles que usam Altap Salamander (2 painéis gerenciador de arquivos): nas opções do pop-up Copiar, apenas especificar os nomes dos arquivos ou máscaras. Fácil.

Eu estou bem com expressões regulares, preguiçoso e avessos a instalações, então eu criei um arquivo de lote que cria o diretório e copia com comandos de baunilha DOS. Parece trabalhoso, mas mais rápido para mim do que trabalhar fora robocopy.

  1. Crie a sua lista de arquivos de origem com caminhos completos, incluindo a letra da unidade, se nec, em um arquivo de texto.
  2. Ligue expressões regulares em seu editor de texto.
  3. Adicione aspas duplas completar cada linha em caso de espaços - busca corda (.*) substituir "\1" corda, e clique substituir todos
  4. Crie duas linhas por arquivo - um para criar o diretório, um para copiar o arquivo (qqq será substituído por caminho de destino) - pesquisa de cadeia (.*) substituir md qqq\1\nxcopy \1 qqq\1\n corda e clique substituir todos
  5. Remova o nome do arquivo a partir dos caminhos de destino - busca \\([^\\^"]+)"\n substituir \\"\n
  6. Substitua no caminho de destino (neste exemplo A:\src e B:\dest). Desligue expressões regulares, pesquisa qqq"A:\src\ substituir B:\dest\ e clique substituir todos.

md irá criar diretórios aninhados. cópia provavelmente se comportam de forma idêntica para xcopy neste exemplo. Você pode querer adicionar / Y para xcopy para confirma sobrescrever reprimir. Você acaba com um arquivo de lote assim:

md "B:\dest\a\b\c\"
xcopy "C:\src\a\b\c\e.xyz" "B:\dest\a\b\c\e.xyz"

repetido para cada arquivo em sua lista original. Testado em Win7.

Para fazer isso com arrastar e uso queda WinZip há opção de uma estrutura dir preservar. Basta criar uma nova .zip no nível do diretório que será seus arquivos raiz e arraste.

Para copiar todos os arquivos de texto para G: e preservar a estrutura de diretórios:

xcopy *.txt /s G:
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top