3 votes

Commande/script pour copier les fichiers avec certains ext, qui peuvent avoir le même nom, de la structure du dossier à un seul répertoire et renommer.

À partir d'une structure de répertoire source (plusieurs dossiers), je dois copier tous les fichiers csv dans un seul répertoire cible. J'ai trouvé une commande pour le faire, mais les fichiers de même nom existent dans différents dossiers de la structure source, ce qui cause des problèmes évidents lorsqu'ils sont copiés dans un seul dossier.

Comment renommer les fichiers dont le nom est en double pendant la copie (idéalement : report.csv, reportcopy2.csv etc) ? Le job ne copie actuellement qu'une seule instance de chaque fichier. Merci pour votre aide.

0voto

Dave Points 25050

Il s'agit d'un léger contournement - je sais que vous vouliez donner un nom différent, mais je me demandais si cela pouvait vous convenir.

Je vous suggère de renommer la copie en quelque chose comme Foldername.Filename.csv.

Utilisez quelque chose comme

echo f | xcopy /f /y srcfile destfile

EDIT

J'ai essayé pendant quelques heures, je ne pense pas que ce que vous voulez soit possible avec l'invite CMD ou les fichiers bat.

Voici ce que j'ai

set sDir=C:\Documents and Settings\drook\Desktop
set dDir="C:\Documents and Settings\drook\Desktop\Folder\"

cd C:\Documents and Settings\drook\Desktop\
FOR /F %%a in ("*.txt") DO (     
    xcopy "%%a" "C:\Documents and Settings\drook\Desktop\Folder\"
    cd\ 
    cd C:\Documents and Settings\drook\Desktop\Folder\
    ren "%%a" "newName-%dir%.txt"
    cd\
    cd C:\Documents and Settings\drook\Desktop\
)

pause

Il échoue lors du renommage car il ignore la variable. Donc, si j'affiche newName-%dir% (où dir est la variable), cela échouerait également pour newName-%%a...

Désolé, je ne pense pas que ce soit possible.

Cela dit, cela donne l'impression que c'est possible : Windows-batch-file-to-copy-and-keep-duplicates

0voto

Scott Points 20468

Ceci est similaire à La réponse d'aflat :

setlocal enableDelayedExpansion
set counter=1
for /r src %%F in (*.csv) do (
    copy %%F dest\%%~nF-!counter!%%~xF
    set /a counter=counter+1
)

0voto

Rich Points 101

Cela devrait le faire :

@echo off
setlocal
set "sourcePath=c:\source"
set "targetPath=c:\temp\target"
set "pattern=*.csv"
set prev=""
set count=0

for /f  "tokens=1,2 delims=?" %%F in ('^(for /r "%sourcePath%" %%N in ^("%pattern%"^) do ^@echo %%~nxN?%%N?^)^|sort') do (
  call :copyFile "%%F" "%%G"
  set prev="%%F"
)

goto :eof

:copyFile
  if /I %prev%==%1 (set /a count+=1) else (set count=0)
  if %count%==0 (set sufix=) else (set sufix=Copy%count%)
  echo copy "%~2" "%targetPath%\%~n1%sufix%%~x1%" 
goto :eof

Ce qu'il fait :

  • Liste tous les fichiers correspondant au motif (le plus interne for ) formaté comme suit nom?chemin
  • Trie la liste (par nom de fichier)
  • Analyse la liste triée ligne par ligne (externe) for ) et pour chaque ligne (fichier)
    • si le nom du fichier apparaît pour la première fois, le copie sans le modifier
    • si le nom du fichier se répète, ajoute le suffixe et le count_nr à une copie

En l'état actuel des choses, il ne fera que répercuter la commande copy au lieu de l'exécuter, vous pouvez donc l'exécuter en toute sécurité et vérifier son résultat. Lorsque vous êtes prêt, supprimez simplement echo de
echo copy "%~2" "%targetPath%\%~n1%sufix%%~x1%"

0voto

flolilo Points 2610

Une simple fonction PowerShell peut également faire cela :

Function Start-FileCopyWDupliCheck(){
    # specify input-path, output-path, renaming-scheme, and file-extension here:
    param(
        [string]$path_in = 'D:\Temp\bla [ ] pfad\[ ]',
        [string]$path_out = 'D:\Temp\mirrbla [123] 123',
        [string]$appendix = "_copy",
        [string]$fileext = "*.*"
    )

    # get all the files (and the necessary attributes)
    [array]$file_input = @(Get-ChildItem -LiteralPath $path_in -Filter $fileext -Recurse)
    [array]$file_input_path = @($file_input | ForEach-Object {$_.FullName})
    [array]$file_input_name = @($file_input | ForEach-Object {$_.BaseName})
    [array]$file_input_ext = @($file_input | ForEach-Object {$_.Extension})

    # check file-names for duplicates:
    for($i = 0; $i -lt $file_input_path.Length; $i++){
        $inter = "$path_out\$($file_input_name[$i])$($file_input_ext[$i])" -replace '[[+]*?()\\.]','\$&'
        if((Test-Path -LiteralPath $inter) -eq $false){
            Write-Host "$inter not found in output-path -> leaving the name the same" -ForegroundColor Green
            $ready_for_copying = $inter
        }else{
            $j = 1
            Write-Host "$inter found in output-path -> appending `"$($appendix)XY`"..." -ForegroundColor Yellow
            while($true){
                $inter = "$path_out\$($file_input_name[$i])$appendix$j$($file_input_ext[$i])" -replace '[[+]*?()\\.]','\$&'
                if((Test-Path -LiteralPath $inter) -eq $true){
                    $j++
                    continue
                }else{
                    Write-Host "$appendix$j is working" -ForegroundColor Green
                    $ready_for_copying = $inter
                    break
                }
            }
        }
        # finally, copy the file:
        Copy-Item -LiteralPath $($file_input_path[$i]) -Destination $ready_for_copying
    }
}

Start-FileCopyWDupliCheck

Bien sûr, on pourrait supprimer les commandes "write-host" - elles fournissent simplement un retour visuel. Il serait également possible de rassembler d'abord les noms de fichiers et de copier ensuite tous les fichiers dans une boucle séparée, ce qui pourrait accélérer les choses.

  • tout simplement $ready_for_copying un tableau,
  • ajouter ( += ) le $inter -valeurs,
  • ajouter la vérification des noms de sortie déjà spécifiés dans le fichier if -conditions (par exemple $inter -in $ready_for_copying ),
  • puis déplacez le copy-item -à une nouvelle for -bloc (par exemple for($i = 0; $i -lt $ready_for_copying.Length; $i++)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X