Batch File: lista todos os arquivos de um tipo, renomeia arquivos, achata o diretório

0

Estou procurando ajuda com um arquivo em lotes que me permita mover todos os arquivos de um tipo específico (* .PDF, por exemplo) para uma nova pasta. No entanto, gostaria de ter recursos não facilmente visíveis para mim. (Eu não sou um programador) incluído no processo (veja as perguntas no final da minha mensagem). Eu pesquisei a web exaustivamente para obter uma solução e não descobri um aplicativo que faz o que eu preciso. Então, vim aqui procurando soluções desenvolvidas. O que descobri é que posso usar o ROBOCOPY para colocar todos os meus arquivos em um diretório usando:

@echo off
set source="R:\Users\Public\"
set destination="R:\Users\Public\All_PDF_Files\"
ROBOCOPY %source% %destination% *.pdf /S /R:1 /W:1 /NDL /XD OutputFolderfor /r %source in (*) do @copy "%destination" .

Mas o que eu não posso determinar como fazer é achatar o diretório depois e obter todos os arquivos em uma pasta. Eu vi um post ou dois (um de um usuário Max que escreveu um arquivo em lotes para achatar o diretório e isso é quase o que eu preciso. Então, a partir de seus arquivos em lote .... Assumindo que eu tenho uma árvore de diretórios contendo apenas diretórios e subdiretórios contendo arquivos PDF ... e uma pasta de destino identificada ... Max apresentou o seguinte ...

Do máximo abaixo ...

Recentemente, tive de lidar com esse problema, e muitos arquivos para os quais eu queria passar da hierarquia para uma única pasta tinham o mesmo nome um do outro, e eu queria ainda achatar a hierarquia sem que eles fiquem escritos . O que fiz foi escrever um script que move o arquivo, mas renomeia-o com o antigo caminho de hierarquia no nome, por exemplo: arquivos de origem:

C: \ files \ somefiles \ file.txt C: \ files \ otherfiles \ file.txt destino é C: \ newdir \ files são criados como C: \ newdir \ somefiles-file.txt C: \ newdir \ otherfiles-file.txt aqui está o código, o arquivo de lote 1 passa pelos arquivos, o arquivo de lote 2 renomeia e move-os (também pode copiar, se você quiser preservar a fonte:

@echo off
for /r %%f in (*.*pr) do @renameandmovefilespart2.bat "%%f" "%%~ff" "%%~xf"

renameandmovefilespart2.bat

@echo off
Setlocal EnableDelayedExpansion
rem set the whole file path
set origWhole=%1
set origPathOnly=%2
set extension=%3
rem here you can set where the directory to hold the flattened hierarchy is
set destDir=c:\destinationDir\
rem  set the directory to do a string replace
rem make this the starting directory, that you dont want in the newly renamed files
set startingDir=C:\starting\directory\
set nothing=
set slash=\
rem here you can set what the character to represent the directory indicator \ in the new files 
set reaplcementDirectoryCharacter=--
set quote="
rem cut out the starting part of the directory
call set newname=%%origWhole:!startingDir!=!nothing!%%
rem replace slashes with new character
call set newname=%%newname:!slash!=!reaplcementDirectoryCharacter!%%
rem remove quotes
call set newname=%%newname:!quote!=!nothing!%%
rem @echo shortened: %newname%
rem @echo source path: %origPathOnly% newPath: %startingDir%
rem @echo extension: %extension%
rem rename the files
ren %origWhole% %newname%
rem prepare to move the file, clean up the source path
call set origPathOnly=%%origPathOnly:!quote!=!nothing!%%
move "%origPathOnly%%newname%" "%destDir%"

Perguntas:

1.) em vez de prefixar o nome do arquivo com a pasta de origem, como posso gastar o nome do arquivo com o local do arquivo de origem? Eu simplesmente reescrevo "%% ~ ff" "%% ~ xf" para "%% FF ~" "%% XF ~"

2.) Eu não quero que os arquivos movidos eu gostaria de simplesmente substituir o arquivo de origem Nota: eu poderia excluir o arquivo de origem, se necessário!

Mais perguntas?

3.) O que (*. * pr) faz no primeiro arquivo de lote do Max?

4.) O que o Max quer dizer com esses (Linha 9) rem torna este o diretório inicial, que você não quer nos arquivos recém-renomeados (linha 10) "rem make this o diretório inicial, que você não quer no arquivos recém-renomeados "no lote 2 acima? Ele está apenas indicando um subdiretório no diretório de origem?

    
por Rich_AT_IADDIC 13.11.2014 / 21:05

1 resposta

0

Se você não estiver limitado a arquivos em lote, aqui está uma solução do PowerShell:

# Setup source and destination paths
$Src = 'c:\source'
$Dst = 'c:\destination'

# Wildcard for filter
$Extension = '*.pdf'

# Get file objects recursively
Get-ChildItem -Path $Src -Filter $Extension -Recurse |
    # Skip directories, because XXX.PDF is a valid directory name
    Where-Object {!$_.PsIsContainer} |
        # For each file
        ForEach-Object {

            # If file exist in destination folder, rename it with directory tag
            if(Test-Path -Path (Join-Path -Path $Dst -ChildPath $_.Name))
            {
                # Get full path to the file without drive letter and replace '\' with '-'
                # [regex]::Escape is needed because -replace uses regex, so we should escape '\'
                $NameWithDirTag = (Split-Path -Path $_.FullName -NoQualifier)  -replace [regex]::Escape('\'), '-'

                # Join new file name with destination directory
                $NewPath = Join-Path -Path $Dst -ChildPath $NameWithDirTag
            }
            # Don't modify new file path, if file doesn't exist in target dir
            else
            {
                $NewPath = $Dst
            }

            # Copy file
            Copy-Item -Path $_.FullName -Destination $NewPath
        }
    
por 24.03.2015 / 20:09