Arquivo em lote: Altere nomes em arquivos com determinadas extensões em vários diretórios com base no nome do diretório e copie em um diretório

0

Eu sou novo em arquivos em lote e em DOS, mas espero que você possa me ajudar de qualquer maneira.

Eu preciso copiar arquivos de um tipo de arquivo específico que estão agora em subdiretórios separados, um desses arquivos por diretório (mas mais arquivos com diferentes tipos de arquivo). Todos eles têm o mesmo nome, portanto, ao copiar para uma nova pasta, o último arquivo a ser copiado é substituído pelo seguinte arquivo ao usar o comando descrito nesta pergunta: Copie arquivos com determinadas extensões de vários diretórios em um diretório .

Seria possível primeiro alterar os nomes dos arquivos para os nomes de seus respectivos diretórios e, em seguida, usar o comando no exemplo? Ou melhor ainda, altere o nome da nova cópia do arquivo antes de colocá-lo no novo diretório ou depois de copiá-lo, mas antes de copiar o seguinte arquivo?

    
por Joel 16.02.2012 / 15:44

2 respostas

1

Ok, aqui está um. Você pode querer considerar o uso de algo mais flexível que um arquivo em lote; um programa C ++ simples teria sido muito mais fácil. O lote não funciona bem com a manipulação de string necessária para extrair o nome do diretório.

@ECHO OFF

SETLOCAL EnableDelayedExpansion

SET _destination=%~1
SHIFT

SET _source=%~1
SHIFT

SET _cmdstring=dir /b /s

:LoopGetExt
    SET _cmdstring=%_cmdstring% "%_source%\*%~1"
    SHIFT
    IF NOT "%~1"=="" GOTO LoopGetExt
::End LoopGetExt

FOR /F "tokens=*" %%i IN ('%_cmdstring%') DO (
        SET _fullpath=%%i
        SET _splitpath=!_fullpath:\=^

!
        SET _filename=%%~ni%%~xi
        FOR /F "tokens=*" %%j IN ("!_splitpath!") DO (
            IF NOT "%%j"=="!_filename!" SET _dirname=%%j
        )

        ECHO "%%i" =^> "%_destination%\!_dirname!_!_filename!"
        COPY "%%i" "%_destination%\!_dirname!_!_filename!"
)

ENDLOCAL

No momento, nada foi codificado: para usá-lo, faça isso.

copyfiles.bat <destination> <source> <ext> [ext]

por exemplo,

copyfiles.bat "C:\Dest" "C:\Source" .txt .xml .csv .log

EDIT (como por solicitação no primeiro comentário)

::copyfiles.bat <destination> <source> <ext> [ext]
::e.g.
::copyfiles.bat "C:\Dest" "C:\Source" .txt .xml .csv .log

@ECHO OFF

SETLOCAL EnableDelayedExpansion

SET _destination=%~1
SHIFT

SET _source=%~1
SHIFT

SET _cmdstring=dir /b /s

:LoopGetExt
    SET _cmdstring=%_cmdstring% "%_source%\*%~1"
    SHIFT
    IF NOT "%~1"=="" GOTO LoopGetExt
::End LoopGetExt

FOR /F "tokens=*" %%i IN ('%_cmdstring%') DO (
        SET _fullpath=%%i
        SET _splitpath=!_fullpath:\=^

!
        SET _filename=%%~ni
        FOR /F "tokens=1 delims=. " %%j IN ("!_splitpath!") DO (
            IF NOT "%%j"=="!_filename!" SET _dirname=%%j
        )

        ECHO "%%i" =^> "%_destination%\!_dirname!%%~xi"
        COPY "%%i" "%_destination%\!_dirname!%%~xi"
)

ENDLOCAL
    
por 17.02.2012 / 15:00
1

Com base no exemplo vinculado, estendi o código para que o nome do arquivo seja alterado para um número crescente, para que todos os arquivos xml sejam copiados para X: \ destination usando o nome do arquivo antigo (inserido por %%~nxf ) um número crescente.

@Echo Off
SET /A counter=1
for /R "X:\source" %%f in (*.xml) do (
    copy "%%f" "X:\destination\%%~nxf_!counter!.xml"
    SET /A counter=!counter!+1
    echo !counter!
)

Observe que você não pode simplesmente executar esse arquivo em lote. Por causa da variável de contador usada no loop for, a "expansão de variável atrasada" precisa ser ativada.

Portanto, se você salvar o script acima como mycopy.cmd , poderá iniciá-lo da seguinte maneira:

cmd.exe /v:on /c "mycopy.cmd"
    
por 16.02.2012 / 16:19