Como copiar uma estrutura de diretório, mas apenas incluir determinados arquivos (usando arquivos do Windows lote)
-
19-08-2019 - |
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
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.
- Crie a sua lista de arquivos de origem com caminhos completos, incluindo a letra da unidade, se nec, em um arquivo de texto.
- Ligue expressões regulares em seu editor de texto.
- Adicione aspas duplas completar cada linha em caso de espaços - busca corda
(.*)
substituir"\1"
corda, e clique substituir todos - 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
(.*)
substituirmd qqq\1\nxcopy \1 qqq\1\n
corda e clique substituir todos - Remova o nome do arquivo a partir dos caminhos de destino - busca
\\([^\\^"]+)"\n
substituir\\"\n
- Substitua no caminho de destino (neste exemplo
A:\src
eB:\dest
). Desligue expressões regulares, pesquisaqqq"A:\src\
substituirB:\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: