Software Frage Projektverzeichnisse von mehreren Laufwerken zusammenführen - benötige Kopierskript

Dieses Thema im Forum "Tech & FAQ Forum" wurde erstellt von Bestatter, 25 Juni 2018.

  1. Bestatter

    Bestatter Schwarzfahrer

    Registriert seit:
    30 Mai 2001
    Beiträge:
    4.894
    Ich muss unter Server 2008 R2 viele Projektordner, die (historisch bedingt) auf 4 Freigaben liegen in einer gemeinsamen Ordnerstruktur zusammen kopieren.

    Bei knapp 900 Projekten ergeben sich gut 3.500 Kopiervorgänge - das geht nur per Skript.
    Leider sind meine Skills für solche Skriptschleifen mit Abfragen aus einer Datei dicht bei null. :o

    Identisch sind immer die Projektnummern mit anschließender Projektbezeichnung (die leider inkonsistent ist).

    Ich habe eine Projektliste als txt-Datei:
    Code:
    [dreistellige Nummer][Projektbezeichnung]
    001 - unser erstes Projekt
    002- schon wieder in schönes Projekt
    003 _ "Projekt 4"
    005 - hiermit werden wir reich
    ...
    Die 3 Ziffern am Anfang gibt es immer, der Rest variiert.


    Mit dieser Liste sollen auf Freigabe "d:\_p\" im Ordner "archiv" neue Ordner entsprechend der Projektliste angelegt werden:
    Code:
    d:\_p\archiv\001 - unser erstes Projekt
    d:\_p\archiv\002- schon wieder in schönes Projekt
    d:\_p\archiv\003 _ "Projekt 4"
    d:\_p\archiv\005 - hiermit werden wir reich
    ...

    In jeden neu angelegten Ordner müssen dann die Verzeichnisstrukturen aus den 4 alten Freigaben in eigene Unterverzeichnisse einkopiert werden.
    Die Bezeichnungen auf den alten Freigaben weichen meist von der Projektliste ab:
    Code:
    d:\_r\001- erstes Projekt       -->  d:\_p\archiv\001 - unser erstes Projekt\LW-R
    d:\_s\001_unser erstes Projekt  -->  d:\_p\archiv\001 - unser erstes Projekt\LW-S
    d:\_t\001 _ erstes Projekt      -->  d:\_p\archiv\001 - unser erstes Projekt\LW-T
    d:\_u\001-Projekt eins          -->  d:\_p\archiv\001 - unser erstes Projekt\LW-U
    ...
    Die ersten 3 Zeichen mit der Projektnummer sind aber immer gleich!

    Die Ordner-Erkennung im Skript basiert also immer auf den ersten 3 Zeichen (der Projektnummer).
    In einigen Fällen existiert ein Projekt nicht auf allen alten Freigaben - dies sollte (wie entstehende Fehler) in einen Log-File.

    Vorab schon mal :icon_prost: für die Hilfe!
    Tom Mix sagt Danke.
  2. DrSnuggles

    DrSnuggles Xanatos

    Registriert seit:
    31 Oktober 2004
    Beiträge:
    20.962
    Lern endlich Powershell.

    Ich erinnere an den Thread hier von Anfang 2017. Hättest du deinen Hintern mal bewegt würdest du das gewünschte Locker in 15 Minuten skripten.
    https://www.cc-community.net/thread...hitektur-im-script-eindeutig-erkennen.113286/

    Schnapp dir ein Buch und lies 2 Tage, das ist dein verdammter Job.

    Warum sollte dir jemand kostenlos deine Arbeit erledigen wenn du überhaupt nicht bereit bist dich weiterzubilden?
    ibinsfei sagt Danke.
  3. SpRuZ

    SpRuZ Beginner

    Registriert seit:
    2 April 2011
    Beiträge:
    1.330
    So ähnlich habe ich das von meinem Schäfer auch schon gehörte. Anträge auf Weiterbildung lehnt er aber regelmäßg ohne Begründung ab. Und so läuft das Schaf weiter im Kreis. ¯\_(ツ)_/¯
    Tom Mix sagt Danke.
  4. EchtAtze

    EchtAtze Bekannter Mitglied

    Registriert seit:
    9 Juni 2001
    Beiträge:
    5.012
    Mein nahezu erstes PowerShell Script.
    Probiere es doch mal aus @Bestatter, sollte eigentlich laufen (ausgiebig habe ich aber nicht getestet).

    Starte eine Command Line und darin eine neue PowerShell, die auch ein Script ausführen darf:

    Code:
    PowerShell.exe -ExecutionPolicy RemoteSigned
    
    Dieses Script z.B. als "CopyProjects.ps1" speichern:

    Code:
    $projectListFilename = "z:\_\Projektliste.txt"
    $targetRoot = "z:\_\p\archiv\"
    $sourceRoots = @("z:\_\r\","z:\_\s\","z:\_\t\","z:\_\u\")
    $sourceTargetFolders = @("LW-R\","LW-S\","LW-T\","LW-U\")
    
    $projects = [ordered]@{}
    
    Get-Content -Path $projectListFilename | ForEach-Object {
      $project =$_.Substring(0,3)
      if($project -match '[0-9][0-9][0-9]') {
      $projects.add( $project, $_ )
      }
    }
    
    for ($index=0; $index -lt $sourceRoots.length; $index++) {
      if(Test-Path -Path $sourceRoots[$index]) {
      Get-ChildItem -Path $sourceRoots[$index] -Directory | ForEach-Object {
      $project = $_.Name.Substring(0,3)
      if($project -match '[0-9][0-9][0-9]') {
      $sourceFolder = $_.FullName
      $projectTargetFolder = $projects[$project]
      $sourceTargetFolder = $sourceTargetFolders[$index]
      New-Item $targetRoot$projectTargetFolder\$sourceTargetFolder -ItemType Directory -Force | Out-Null
      Copy-Item -Path $sourceFolder\* -Recurse -Force -Destination $targetRoot$projectTargetFolder\$sourceTargetFolder
      }
      }
      }
    }
    
    und in der PowerShell aufrufen:

    Code:
    .\CopyProjects.ps1
    
    Edit:
    Die Formatierung des Scripts ist hier im Form irgendwie verloren gegangen...
    Tom Mix sagt Danke.
  5. Bestatter

    Bestatter Schwarzfahrer

    Registriert seit:
    30 Mai 2001
    Beiträge:
    4.894
    OK, es war kontraproduktiv nicht in #1 meinen verreckten Ansatz zu packen.
    Besser später, als nie:
    Code:
    chcp 65001
    for /f "tokens=*" %%x in (ap.txt) do (
    mkdir "archiv\%%x" >> log.txt
    set proj=%%x
    set proj=%proj:~0,3%
    echo.%proj%
    )
    ap.txt ist dabei meine Testdatei:
    Code:
    001 - unser erstes Projekt
    002- schon wieder in schönes Projekt
    003 _ Projekt 4
    005 - hiermit werden wir reich
    Schon dass finden von "chcp 65001" war eine längere Sucherei nach einer Lösung zur Rettung der Umlaute.
    Das Ergebnis davon ist ambivalent:
    Code:
    d:\_Archivprojekte_zusammen>apm
    
    d:\_Archivprojekte_zusammen>chcp 65001
    Aktive Codepage: 65001.
    
    d:\_Archivprojekte_zusammen>for /F "tokens=*" %x in (ap10.txt) do (
    rem mkdir "archiv\%x" >> log.txt
    set proj=%x
    set proj=005
    echo.005
    )
    
    d:\_Archivprojekte_zusammen>(
    rem mkdir "archiv\001 - unser erstes Projekt" >> log.txt
    set proj=001 - unser erstes Projekt
    set proj=005
    echo.005
    )
    005
    
    d:\_Archivprojekte_zusammen>(
    rem mkdir "archiv\002- schon wieder in schönes Projekt" >> log.txt
    set proj=002- schon wieder in schönes Projekt
    set proj=005
    echo.005
    )
    005
    
    d:\_Archivprojekte_zusammen>(
    rem mkdir "archiv\003 _ Projekt 4" >> log.txt
    set proj=003 _ Projekt 4
    set proj=005
    echo.005
    )
    005
    
    d:\_Archivprojekte_zusammen>(
    rem mkdir "archiv\004-Projektstraße 123" >> log.txt
    set proj=004-Projektstraße 123
    set proj=005
    echo.005
    )
    005
    
    d:\_Archivprojekte_zusammen>(
    rem mkdir "archiv\005 - hiermit werden wir reich" >> log.txt
    set proj=005 - hiermit werden wir reich
    set proj=005
    echo.005
    )
    005
    Die neuen Ordner werden mit Umlauten erstellt, aber das Separieren der ersten drei Stellen des Projektnamens liefert immer nur 005.
    Danach hatte ich #1 erstellt.


    @EchtAtze
    Danke! Wird mein Erstkontakt mit Powershell ...


    Nein ist es nicht.
    Im Gegensatz zu Dir kenne ich meine Arbeitsplatzbeschreibung.
    Trotzdem setze ich mich täglich mit IT und ihren Problemen auseinander.
    Deine "Perfekter-Admin-Schablone" passt nicht bei mir, weil sie mir bei meinem Job auch viel zu eng wäre.
    Das alles habe ich Dir nach Deiner letzten "Ansage" auch schon per PN erklärt ...
  6. DrSnuggles

    DrSnuggles Xanatos

    Registriert seit:
    31 Oktober 2004
    Beiträge:
    20.962
    Dann such deiner Firma eine Fachkraft.

    So ein Gestümper findet bei uns nicht mal in der Kirchengemeinde statt.
  7. Bestatter

    Bestatter Schwarzfahrer

    Registriert seit:
    30 Mai 2001
    Beiträge:
    4.894
    @DrSnuggles
    Setz mich bitte auf Deine Ignorierliste!

    Ich schätze Dein fachliches Wissen, aber Deine Titan-Scheuklappen gegenüber anderen beruflichen Realitäten nerven!
    Tom Mix sagt Danke.
  8. ibinsfei

    ibinsfei Team (Technik) Mitarbeiter

    Registriert seit:
    12 August 2001
    Beiträge:
    6.484
    Sorry @Bestatter, aber der Doc hat vollkommen Recht. Entweder ist es dein Job solche Dinge zu erledigen, dann solltest du dir auch das Handwerkszeug dazu aneignen, oder es ist nicht den Job, dann solltest du das denjenigen machen lassen, dessen Job es ist.
  9. SkAvEnGeR

    SkAvEnGeR Master of Tools

    Registriert seit:
    21 Mai 2001
    Beiträge:
    5.384
    @Bestatter :
    in deinem Script sind alle SET-Befehle nicht in "" - obwohl sie Leerzeichen enthalten, das kann mMn schon nicht funktionieren.
    wenn du Werte in eine Variable übernehmen willst, muss der Interpreter ja auch wissen, wann die Variable aufhört und wann evtl. weitere Befehle folgen

    und zwei SET-Befehle direkt nacheinander, die beide in die gleiche Variable schreiben, führen da auch zum Fehler. set proj=005 wiederholt sich ständig, das muss ja zu Fehlern führen
    Tom Mix sagt Danke.
  10. SkAvEnGeR

    SkAvEnGeR Master of Tools

    Registriert seit:
    21 Mai 2001
    Beiträge:
    5.384
    Weiterhin: von wie vielen Projekt-Ordnern sprechen wir hier eigentlich?
    So lange, wie der Thread schon offen ist - da wäre man zu Fuß wohl schon fertig
    Tom Mix sagt Danke.
  11. SkAvEnGeR

    SkAvEnGeR Master of Tools

    Registriert seit:
    21 Mai 2001
    Beiträge:
    5.384
    Ich würde ausserdem das ganze in zwei Teilaufgaben trennen:

    1. alle Ordner von Projekt 001 in neu nummerierter Reihenfolge umbenennen
    2. dann die "INHALTE" der neu benannten Ordner in die neuen Unterordner kopieren

    letztlich kommtr es hier aber auch auf die Datenmenge und die Anzahl von Projekten an, bei riesigen Datenmengen kann das evtl. auch aus dem Ruder laufen
    Tom Mix sagt Danke.
  12. Bestatter

    Bestatter Schwarzfahrer

    Registriert seit:
    30 Mai 2001
    Beiträge:
    4.894
    ca. 900 Projekte auf 4 Freigaben mit Unterordnern und Dateien -> viel!
    Ich arbeite in eine 40 Stunden Woche zwischen 45 und 60 Stunden in Projekten und administriere -> keine Zeit für eine Händische Lösung

    Danke!

    Da das Erzeugen der Unterordner aus "ap.txt"
    Code:
    001 - unser erstes Projekt
    002- schon wieder in schönes Projekt
    003 _ Projekt 4
    005 - hiermit werden wir reich
    klappt, habe ich die Schleife zum Kürzen der Verzeichnisnamen mal heraus gelöst:
    Code:
    chcp 65001
    for /f "tokens=*" %%y in (ap10.txt) do (
    set "projkurz=%%y:~0,3%"
    echo.%projkurz%
    set "projkurz="
    )
    %%y liefert zwar der Reihe nach die 4 Projektnamen, aber das Kürzen auf die ersten 3 Ziffern klappt nicht.
    Das wiederholte "echo.005" oben in #5 lag wohl daran, dass ich die Variable nicht zurück gesetzt habe.

    Leider funktioniert es mit "projkurz=%%y:~0,3%" immer noch nicht:
    Code:
    d:\_Archivprojekte_zusammen>apm.bat
    d:\_Archivprojekte_zusammen>set "projkurz="
    
    d:\_Archivprojekte_zusammen>for /F "tokens=*" %y in (ap10.txt) do (
    set "projkurz=%y:~0,3"
    echo.
    set "projkurz="
    )
    
    d:\_Archivprojekte_zusammen>(
    set "projkurz=001 - unser erstes Projekt:~0,3"
    echo.
    set "projkurz="
    )
    
    
    d:\_Archivprojekte_zusammen>(
    set "projkurz=002- schon wieder in schönes Projekt:~0,3"
    echo.
    set "projkurz="
    )
    
    
    d:\_Archivprojekte_zusammen>(
    set "projkurz=003 _ Projekt 4:~0,3"
    echo.
    set "projkurz="
    )
    
    
    d:\_Archivprojekte_zusammen>(
    set "projkurz=005 - hiermit werden wir reich:~0,3"
    echo.
    set "projkurz="
    )

    @DOC und ibinsfei
    "Schön", dass Ihr bereits eine Meinung habt und Euch keine weiteren für andere Szenarien bilden braucht.
    Ich arbeite nun mal in der diffusen Grauzone zwischen Projektarbeit meines studierten Berufes und der Administration.
    Bei hunderten Überstunden fange ich eben nicht noch mit dem Lernen von Powershell an.
    Trotzdem müsst Ihr nicht weiteres Adrenalin verplempern - die Server werden von einem Softwarehaus betreut.
    Wie ich so ein Problem per Skript zu lösen kann, interessiert mich aber dennoch ...
    Tom Mix und rick_s sagen Danke.
  13. ibinsfei

    ibinsfei Team (Technik) Mitarbeiter

    Registriert seit:
    12 August 2001
    Beiträge:
    6.484
    Wenn du pro Woche bis zu 20 Überstunden machst, und das auch weil du Dinge machst, die nicht dein Job sind und die auch nicht in deine Qualifikationen fallen, dann liegt genau dort das Problem.
    Du solltest die Eier haben, deinem Chef zu sagen, "Sorry, dass ist nicht mein Metier und gehört auch nicht zu meinen Aufgaben, abgesehen davon habe ich sowieso schon zu viele Überstunden."
    Sag ihm auch, dass er sich jemanden für dieAdministration besorgen soll, dessen Handwerk das auch ist.
    Das soll jetzt keine Kritik an deinen Fähigkeiten sein, versuche sie nur richtig einzusetzen.
  14. Tom Mix

    Tom Mix Current User

    Registriert seit:
    1 Juni 2001
    Beiträge:
    1.584
    @Bestatter
    ich druecke die daumen und bin gespannt wie's ausgeht :p
    damit du die hoffnung nicht aufgibst, hier eine 'gute-alte-erfolgs-story'
    aus einer zeit
    bevor
    mutmassliche zivilversager
    unschuldige themen
    sinnfrei und motivationsarm
    zuspammten:
    https://www.cc-community.net/thread...ungsdatum-der-datei-setzen.26391/#post-269781

    @board
    weil der knopf dafuer fehlt, hier very-wichtig getippt:
    #02 - talk to the paw...
    #06 - talk to the paw...
    #08 - talk to the paw...
    #13 - talk to the paw...
    Bestatter sagt Danke.
  15. dr_tommi

    dr_tommi alter Oldie

    Registriert seit:
    26 April 2001
    Beiträge:
    12.301
    @Bestatter
    Unabhängig von der Diskussion ob man das nun mit Powershell, Batch oder einem externen Programmierer löst, kann ich dir zumindest bei dem Problem mit der Zerlegung helfen.
    Innerhalb von Schleifen ist die Behandlung von Variablen etwas eigenwillig.
    Um dort tatsächlich sinnvoll mit Variablen arbeiten zu können gibt es zwei Wege. Entweder die Benutzung des Parameters "SETLOCAL EnableDelayedExpansion" oder die Auslagerung der Behandlung in eine "Subroutine".

    Hier mal ein Beispiel zu deinem Problem:

    Code:
    chcp 1252
    for /f "tokens=*" %%x in (ap.txt) do (call :subroutine "%%x")
    GOTO :eof
    
    :subroutine   
    set "prj=%1"
    set prj=%prj:~1,3%
    echo.%prj%
    GOTO :eof
    
    In der Subroutine wird der Übergabeparameter mit %1 angesprochen und enthält hier auch die Anführungsstriche. Deshalb auch ~1,3 bei der Zerlegung.

    Übrigens funktioniert die Codepage 1252 auch prima, zumindest bei mir.
    Bei mir werden die Verzeichnisse selten in UTF-8 (Codepage 65001) angelegt. ;)
    Bestatter sagt Danke.
  16. Bestatter

    Bestatter Schwarzfahrer

    Registriert seit:
    30 Mai 2001
    Beiträge:
    4.894
    Sicher gut. :yo
    Zum Glück ist noch bis Ende des Jahres Zeit, das umzusetzen.
    Jetzt ist aber erst einmal der Endspurt bis zum Urlaub angesagt.


    Perfekt, vielen Dank an "Code-Chef dr_tommi"! ;)
  17. taurec

    taurec Bekanntes Mitglied

    Registriert seit:
    21 Mai 2001
    Beiträge:
    1.244
    Die Arroganz von manchen ist wirklich... es gibt Menschen die finden keinen Zugang zu scripten und programmieren. Ist so.
    Hier ein Tool das diesen Job eventuell erledigen kann. Viel Glück. (bin ich froh aus diesem Admin Irrsinn raus zu sein).....

    https://2xdsoft.de.tl/Folder-Merger.htm
  18. Bestatter

    Bestatter Schwarzfahrer

    Registriert seit:
    30 Mai 2001
    Beiträge:
    4.894
    @taurec
    Ich habe schon Zugang zu Skripten, aber ab einer gewissen Komplexität (siehe #15) oder bei Regex bin ich ohne Beispiele draußen.

    Danke für den Tipp! :)
    Das Tool scheint nur geeignet, einen der ca. 900 Merge-Prozesse abzubilden.
    Eine Schleife, die den 4 Ausgangsordnern und dem einen Zielordner mit 4 Unterverzeichnissen immer nur die ersten 3 Zeichen des Ordnernamens berücksichtigt, ist damit wohl nicht möglich.

    In #1 hatte ich das schon mal so dargestellt:
    Code:
    d:\_r\001- erstes Projekt         -->  d:\_p\archiv\001 - unser erstes Projekt\LW-R
    d:\_s\001_unser erstes Projekt    -->  d:\_p\archiv\001 - unser erstes Projekt\LW-S
    d:\_t\001 _ erstes Projekt        -->  d:\_p\archiv\001 - unser erstes Projekt\LW-T
    d:\_u\001-Projekt eins            -->  d:\_p\archiv\001 - unser erstes Projekt\LW-U
    d:\_r\002[beliebige Zeichenfolge] -->  d:\_p\archiv\002 - unser zweites Projekt\LW-R
    d:\_s\002[beliebige Zeichenfolge] -->  d:\_p\archiv\002 - unser zweites Projekt\LW-S
    d:\_t\002[beliebige Zeichenfolge] -->  d:\_p\archiv\002 - unser zweites Projekt\LW-T
    d:\_u\002[beliebige Zeichenfolge] -->  d:\_p\archiv\002 - unser zweites Projekt\LW-U
    ...
    Die Ausgangs- und Zielordner müssen also immer anhand der ersten 3 Zeichen des Pfadnamens "erkannt" werden, fehlende Ausgangsordner müssen ignoriert werden.

    Den Einstieg mit dem Anlegen der Zielordner nach Projektliste und dem Separieren der ersten 3 Zeichen habe ich ja schon mal.
    Damit werde ich später weiter forschen.