Befehl / Skript zum Kopieren von Dateien mit bestimmten ext, die möglicherweise den gleichen Namen haben, von der Ordnerstruktur in das Einzelverzeichnis und zum Umbenennen

2

Aus einer Quellverzeichnisstruktur (mehrere Ordner) muss ich alle CSV-Dateien in ein einziges Zielverzeichnis kopieren. Ich habe einen Befehl gefunden, um dies zu tun, obwohl Dateien mit demselben Namen in verschiedenen Ordnern der Quellstruktur vorhanden sind, was offensichtliche Probleme beim Kopieren in einen Ordner verursacht.

Wie können die Dateien mit doppelten Namen beim Kopieren bitte umbenannt werden (im Idealfall: report.csv, reportcopy2.csv etc)? Der Job kopiert derzeit nur eine einzelne Instanz jeder Datei. Danke für die Hilfe.

Nick
quelle

Antworten:

0

Dies ist eine leichte Arbeit - ich weiß, dass Sie einen anderen Namen haben wollten, aber ich habe mich gefragt, ob dies für Sie funktionieren wird.

Ich würde vorschlagen, dass Sie beim Kopieren den Namen in "Ordnername.Dateiname.csv" ändern.

Verwenden Sie so etwas wie

echo f | xcopy /f /y srcfile destfile

BEARBEITEN

Ich habe es einige Stunden lang versucht, ich glaube nicht, dass das, was Sie wollen, mit der CMD-Eingabeaufforderung oder den Bat-Dateien möglich ist.

Das habe ich

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

Das Umbenennen schlägt fehl, da die Variable ignoriert wird. Wo also newName-% dir% angezeigt wird (wo dir die Variable ist), schlägt dies auch bei newName - %% a fehl ...

Entschuldigung, ich glaube nicht, dass es möglich ist.

Trotzdem sieht es so aus, als ob es möglich wäre: Windows-Batch-Datei-zu-kopieren-und-behalten-Duplikate

Dave
quelle
Vielen Dank, Dave. Im Moment verwende ich FOR / R "src" %% a in ("* .csv") DO xcopy / d / y "%% a" "dest". Unsicher, wie eine Namensänderung integriert werden soll. Vielen Dank
Nick
Ein bisschen mehr Info - rund 500 Dateien von 3000 werden anfangs mit vielleicht vier oder fünf gleichen Gruppen kopiert.
Nick
0

Das ist ähnlich wie Antwort von aflat :

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

Dies sollte es tun:

@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

Was es macht:

  • Listet alle Dateien auf, die mit dem Muster übereinstimmen (am innersten) for ) formatiert als Name? Pfad
  • Sortiert die Liste (nach Dateinamen)
  • Analysiert die sortierte Liste zeilenweise (äußere for ) und für jede Zeile (Datei)
    • Wenn der Dateiname zum ersten Mal angezeigt wird, wird er unverändert kopiert
    • Wenn sich der Dateiname wiederholt, werden Suffix und count_nr zu einer Kopie hinzugefügt

So wie es jetzt ist, wird der Kopierbefehl nur wiederholt, anstatt ausgeführt zu werden, sodass Sie ihn sicher ausführen und seine Ausgabe überprüfen können. Wenn Sie fertig sind, entfernen Sie einfach echo von
echo copy "%~2" "%targetPath%\%~n1%sufix%%~x1%"

wmz
quelle
0

Eine einfache PowerShell-Funktion kann dies auch tun:

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

Natürlich könnte man die "Write-Host" -Befehle entfernen - sie geben einfach ein paar visuelle Rückmeldungen. Es wäre auch möglich, zuerst die Dateinamen zu sammeln und später alle Dateien in einer separaten Schleife zu kopieren, was möglicherweise die Dinge beschleunigt.

  • einfach machen $ready_for_copying eine Anordnung,
  • hinzufügen ( += ) das $inter -Werte dazu,
  • füge die Prüfung für bereits spezifizierte Ausgabenamen in das ein if -Bedingungen (z. $inter -in $ready_for_copying ),
  • dann bewegen Sie die copy-item -Befehl an einen neuen for -Block (z. for($i = 0; $i -lt $ready_for_copying.Length; $i++)
flolilolilo
quelle