Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Hilfe bei Shell Script zum verschieben von Ordnern

Frage Entwicklung Batch & Shell

Mitglied: mqlmann

mqlmann (Level 1) - Jetzt verbinden

10.07.2014, aktualisiert 11.07.2014, 1165 Aufrufe, 14 Kommentare

Hallo,

ich versuche gerade ein Script zu bauen, das folgendes können soll:

1. Einen bestimmten Pfad nach Ordnern mit einem bestimmten Namen durchsuchen (in diesem Fall "Avid1_TEMP")
das klappt auch schon ganz gut mit folgendem Code:
01.
Get-ChildItem $QuellPfad -Recurse | Where { $_.PSIsContainer } | Where { $_ -match "Avid1_TEMP" } | Select-Object FullName
2. innerhalb der gefunden Ordner zwei Ordner tiefer gehen (es sind in jedem Fall immer genau zwei Ordner) und die dort vorhandenen Ordner nach
Datum umbenennen und nummerieren. Das umbenennen bekomme ich auch hin:
01.
$Datum = Get-Date -format "yyyyMMdd"  
02.
$Nr = 1  
03.
Get-ChildItem $QuellPfadTiefer | ForEach-Object {$_ | Rename-Item -NewName ("$Datum{0}" -f $Nr++)}
Aber ich habe noch keinen blassen Schimmer wie ich die Variable
01.
$QuellPfadTiefer

also die unter Punkt 1 gefundenen Treffer + zwei Ordner tiefer definieren kann.

3. Erschwerend kommt hinzu, dass am Ende die umbenannten Ordner innerhalb des Überordners der Pfade aus Punkt 1 in andere Ordner verschoben werden sollen. Hier habe ich noch nicht einmal Ansätze.

Im Prinzip soll das Ganze so aussehen

1. Pfad1\Avid1_TEMP\OrdnerA\OrdnerB\(hier gibts dann z.B. drei Ordner mit unbekanntem Namen)
wird umbenannt zu
2. Pfad1\Avid1_TEMP\OrdnerA\OrdnerB\(201407101 + 201407102 + 201407103)
und verschoben nach
3. Pfad1\ZielOrdnerA\ZielOrdnerB\(201407101 + 201407102 + 201407103)

Ich hoffe es blickt hier jemand durch das Chaos in meinem Kopf und hat noch einen Tipp wie ich das realisieren kann!

Vielen Dank
Mitglied: colinardo
11.07.2014, aktualisiert um 10:44 Uhr
Moin mqlman,
also bis zu Punkt 2 konnte ich deiner Beschreibung folgen, das sähe dann so aus:
01.
$quellpfad = "C:\temp\quelle" 
02.
$quellpfadtiefer = "\OrdnerA\OrdnerB" 
03.
$folders = dir $quellpfad -Recurse | ?{$_.PSIsContainer -and $_.Name -like "Avid1_TEMP"} 
04.
foreach ($folder in $folders){ 
05.
    $cnt=0 
06.
    dir "$($folder.FullName)$quellpfadtiefer" | ?{$_.PSIsContainer} | %{Rename-Item $_.FullName -NewName ((get-date -Format "yyyyMMdd")+$cnt++)} 
07.
}
aber Punkt 3 (das Verschieben), ist mir nicht klar wie sich hier die Pfade genau zusammensetzen sollen. Bitte beschreibe das mal etwas verständlicher.

Grüße Uwe
Bitte warten ..
Mitglied: mqlmann
11.07.2014 um 17:25 Uhr
Hallo Uwe,

es ist mir regelrecht unangenehm, dass immer Du es bist, der mir auf die Sprünge helfen muss ;)

Die umbenannten Ordner, die mit deinem Code jetzt unter
C:\temp\quelle\OrdnerA\OrdnerB\(umbenannte Ordner: 201407101 + 201407102 + 201407103)
liegen, muss ich verschieben nach
C:\temp\quelle\
und dort in andere Unterordner rein. Also am Ende sollte das so in der Art aussehen:
C:\temp\quelle\OrdnerA1\OrdnerB1\(umbenannte Ordner: 201407101 + 201407102 + 201407103)

Wenn ich Deinen Code richtig verstehe sollte das doch so funktionieren:
01.
$quellpfad = "C:\temp\quelle" 
02.
$quellpfadtiefer = "\OrdnerA\OrdnerB" 
03.
$quellpfadtieferNEU = "\OrdnerA1\OrdnerB1" 
04.
$folders = dir $quellpfad -Recurse | ?{$_.PSIsContainer -and $_.Name -like "Avid1_TEMP"} 
05.
foreach ($folder in $folders){ 
06.
    $cnt=0 
07.
    dir "$($folder.FullName)$quellpfadtiefer" | ?{$_.PSIsContainer} | %{Rename-Item $_.FullName -NewName ((get-date -Format "yyyyMMdd")+$cnt++)} | Move-Item "$($folder.FullName)$quellpfadtiefer" "$($folder.FullName)$quellpfadtiefer" "$($folder.FullName)$quellpfadtieferNEU" 
08.
}
?

Viele Grüße
Bitte warten ..
Mitglied: colinardo
11.07.2014, aktualisiert um 21:53 Uhr
Zitat von mqlmann:
es ist mir regelrecht unangenehm, dass immer Du es bist, der mir auf die Sprünge helfen muss ;)
kein Thema, irgendeiner muss es ja machen
Wenn ich Deinen Code richtig verstehe sollte das doch so funktionieren:
Nicht ganz, wenn du alle umbenannten Ordner in diese Ordnerfolge packen willst, Hier würde es ja sonst zu Dulikaten kommen, also muss der Counter außerhalb der Schleife initialisiert werden und der Move-Befehl war auch nicht ganz korrekt.
Bitte warten ..
Mitglied: mqlmann
11.07.2014 um 21:38 Uhr
Hallo Uwe,

vielen Dank für deine Geduld!
Ich versuche das Ganze nochmal nachvollziehbarer zu erklären.

1. Es gibt den Hauptordner, der auf Unterordner mit Namen "Avid1_TEMP" durchsucht werden soll. Hier nenne ich ihn mal wie in Deinem Code:

C:\temp

2. In diesem Ordner gibt es zwei Unterordner:

C:\temp\Avid MediaFiles
C:\temp\Avid1_TEMP

3. Innerhalb des Ordners "Avid MediaFiles" sieht es wie folgt aus:

C:\temp\Avid MediaFiles\MXF

4. Innerhalb des Ordners "Avid1_TEMP" sieht es wie folgt aus:

C:\temp\Avid1_TEMP\Avid MediaFiles\MXF

5. In dem Ordner "MXF" liegen die Ordner, die mit dem Script nach Datum nummeriert umbenannt wurden:

C:\temp\Avid1_TEMP\Avid MediaFiles\MXF\201407101
C:\temp\Avid1_TEMP\Avid MediaFiles\MXF\201407102
C:\temp\Avid1_TEMP\Avid MediaFiles\MXF\201407103

6. Diese Ordner sollen nach der Umbenennung in folgenden Ordner verschoben werden:

C:\temp\Avid MediaFiles\MXF

7. Sodass das Ganze dann so aussieht:

C:\temp\Avid1_TEMP\Avid MediaFiles\MXF\ -- leer --
C:\temp\Avid MediaFiles\MXF\201407101
C:\temp\Avid MediaFiles\MXF\201407102
C:\temp\Avid MediaFiles\MXF\201407103

Ich hoffe das war zielführend ;)


Vielen Dank
Bitte warten ..
Mitglied: colinardo
LÖSUNG 11.07.2014, aktualisiert um 22:58 Uhr
01.
$quellpfad = "C:\temp" 
02.
$quellpfadtiefer = "\Avid MediaFiles\MXF" 
03.
$folders = dir $quellpfad -Recurse | ?{$_.PSIsContainer -and $_.Name -like "Avid1_TEMP"} 
04.
foreach ($folder in $folders){ 
05.
    $cnt=0 
06.
    dir "$($folder.FullName)$quellpfadtiefer" | ?{$_.PSIsContainer} | %{Rename-Item $_.FullName -NewName ((get-date -Format "yyyyMMdd")+$cnt++) -passthru } | Move-Item -Destination "$($folder.parent.FullName)$quellpfadtiefer" 
07.
}
Bitte warten ..
Mitglied: mqlmann
11.07.2014 um 22:32 Uhr
Das funtioniert gut!
Leider, leider habe ich ein wichtiges Detail übersehen:

1. Im Quellordner

C:\temp

2. gibt es noch einen Unterordne, deren Namen nicht vorhersehbar sind:

C:\temp\UnbekannterOrdner1
C:\temp\UnbekannterOrdner2

3. Und erst da drin gibt es die Struktur

C:\temp\UnbekannterOrdner1\Avid MediaFiles
C:\temp\UnbekannterOrdner1\Avid1_TEMP
C:\temp\UnbekannterOrdner2\Avid MediaFiles
C:\temp\UnbekannterOrdner2\Avid1_TEMP

---

7. Das heisst am Ende muss das so aussehen:

C:\temp\UnbekannterOrdner1\Avid1_TEMP\Avid MediaFiles\MXF\ -- leer --
C:\temp\UnbekannterOrdner2\Avid1_TEMP\Avid MediaFiles\MXF\ -- leer --
C:\temp\UnbekannterOrdner1\Avid MediaFiles\MXF\201407101
C:\temp\UnbekannterOrdner1\Avid MediaFiles\MXF\201407102
C:\temp\UnbekannterOrdner1\Avid MediaFiles\MXF\201407103
C:\temp\UnbekannterOrdner2\Avid MediaFiles\MXF\201407101
C:\temp\UnbekannterOrdner2\Avid MediaFiles\MXF\201407102
C:\temp\UnbekannterOrdner2\Avid MediaFiles\MXF\201407103

Gibt es einen Weg den Namen diese Ordners bei der Suche mit
01.
dir $quellpfad -Recurse | ?{$_.PSIsContainer -and $_.Name -like "Avid1_TEMP"}
in eine Variable zu bringen?

Sorry, aber das hatte ich echt nicht bedacht - Asche auf mein Haupt!
Bitte warten ..
Mitglied: colinardo
11.07.2014, aktualisiert um 22:53 Uhr
ist oben angepasst...

du siehst ... fürs nächste mal direkt detaillierte Angaben machen. Beim Skripten kommt es eben auf kleinste Details an.

standby for the next change

good night.
Bitte warten ..
Mitglied: mqlmann
11.07.2014 um 22:58 Uhr
Respekt Uwe!
Wenn ich Dir ein Bier mailen könnte würde ich es glatt machen ;)

Vielen Dank!!
Bitte warten ..
Mitglied: mqlmann
23.07.2014 um 21:22 Uhr
Hallo Uwe,

das Script läuft super. Dummerweise habe ich hier @home nie darüber nachgedacht, dass der Speicher, den das Script durchsuchen soll, relativ groß ist (30TB um genau zu sein). Dementsprechen lange dauert die Ausführung, ich habe zwischen 20s und 30s gemessen.
Was mich natürlich auf zwei Fragen bringt: Kann das Get-ChildItem Cmdlt irgendwie beschleunigen?
Und noch eine grundsätzliche Frage: Wie kann ich eine Form aufrufen während das Script läuft? Das Einfachste wäre hier natürlich dem User die Info zu geben, dass das Script gerade umbenennt und verschiebt.

Viele Grüße
Bitte warten ..
Mitglied: colinardo
23.07.2014, aktualisiert um 21:43 Uhr
Hi,
Zitat von mqlmann:
das Script läuft super. Dummerweise habe ich hier @home nie darüber nachgedacht, dass der Speicher, den das Script
durchsuchen soll, relativ groß ist (30TB um genau zu sein). Dementsprechen lange dauert die Ausführung, ich habe
zwischen 20s und 30s gemessen.
Was mich natürlich auf zwei Fragen bringt: Kann das Get-ChildItem Cmdlt irgendwie beschleunigen?
Wenn du Powershell mit mindestens Version 3.0 hast eventuell ja. Deine aktuelle Powershellversion kannst du dir mit folgendem Befehl anzeigen lassen:
$psversiontable.PSVersion.toString()
Wenn du noch 2.0 hast, upgraden...
Und noch eine grundsätzliche Frage: Wie kann ich eine Form aufrufen während das Script läuft? Das Einfachste
wäre hier natürlich dem User die Info zu geben, dass das Script gerade umbenennt und verschiebt.

das Script hier läuft ab PS3.0 und müsste es vermutlich beschleunigen und zeigt eine Info an während das Script läuft:
01.
$myjob = [Powershell]::Create().AddScript({ 
02.
    $quellpfad = "C:\temp" 
03.
    $quellpfadtiefer = "\Avid MediaFiles\MXF" 
04.
    $folders = dir $quellpfad -Filter "Avid1_TEMP" -Recurse -Directory 
05.
    foreach ($folder in $folders){ 
06.
        $cnt=0 
07.
        dir "$($folder.FullName)$quellpfadtiefer" -Directory | %{Rename-Item $_.FullName -NewName ((get-date -Format "yyyyMMdd")+$cnt++) -passthru } | Move-Item -Destination "$($folder.parent.FullName)$quellpfadtiefer" 
08.
09.
}) 
10.
$myjob.BeginInvoke()| out-null 
11.
 
12.
while($myjob.InvocationStateInfo.State -eq "Running"){ 
13.
    Write-Progress -Activity "Ordnerverarbeitung" -Status "Bitte warten Umbenennung läuft ..." 
14.
15.
write-host "Vorgang abgeschlossen!"
Grüße Uwe
Bitte warten ..
Mitglied: mqlmann
23.07.2014 um 22:09 Uhr
Hallo Uwe,

wie immer: vielen Dank für Deine Schnelle Antwort!
Ich arbeite mit Powershell3.

Kann ich denn statt
01.
Write-Progress -Activity "Ordnerverarbeitung" -Status "Bitte warten Umbenennung läuft ..."
das auch in in einer System.Windows.Forms.Form mit selbigem Text anzeigen lassen?
Wenn ich an dieser Stelle einfach eine Form ohne Buttons einsetze, wird das Script erst beendet sobald ich die Form schließe.
Bitte warten ..
Mitglied: mqlmann
24.07.2014 um 20:25 Uhr
Hallo Uwe,

in diesem Fall brauche ich keine Progressbar. Es würde mir völlig reichen ein Fenster mit "Es wird umbenannt..." oder so anzeigen zulassen, während das Script läuft.
Bitte warten ..
Mitglied: colinardo
24.07.2014 um 20:48 Uhr
01.
 
02.
function GenerateForm { 
03.
#region Import the Assemblies 
04.
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null 
05.
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null 
06.
#endregion 
07.
 
08.
#region Generated Form Objects 
09.
$form1 = New-Object System.Windows.Forms.Form 
10.
$label1 = New-Object System.Windows.Forms.Label 
11.
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState 
12.
#endregion Generated Form Objects 
13.
 
14.
 
15.
$handler_form1_Shown=  
16.
17.
    #------------ Arbeitscode --------------- 
18.
     
19.
    $quellpfad = "C:\temp" 
20.
    $quellpfadtiefer = "\Avid MediaFiles\MXF" 
21.
    $folders = dir $quellpfad -Recurse | ?{$_.PSIsContainer -and $_.Name -like "Avid1_TEMP"} 
22.
    foreach ($folder in $folders){ 
23.
        $cnt=0 
24.
        dir "$($folder.FullName)$quellpfadtiefer" | ?{$_.PSIsContainer} | %{Rename-Item $_.FullName -NewName ((get-date -Format "yyyyMMdd")+$cnt++) -passthru } | Move-Item -Destination "$($folder.parent.FullName)$quellpfadtiefer" 
25.
26.
 
27.
 
28.
    # ------------------------------------ 
29.
     
30.
    #Form schließen wenn fertig 
31.
    $form1.Close() 
32.
 
33.
34.
 
35.
$OnLoadForm_StateCorrection= 
36.
{#Correct the initial state of the form to prevent the .Net maximized form issue 
37.
	$form1.WindowState = $InitialFormWindowState 
38.
39.
 
40.
#---------------------------------------------- 
41.
#region Generated Form Code 
42.
$System_Drawing_Size = New-Object System.Drawing.Size 
43.
$System_Drawing_Size.Height = 65 
44.
$System_Drawing_Size.Width = 325 
45.
$form1.ClientSize = $System_Drawing_Size 
46.
$form1.ControlBox = $False 
47.
$form1.DataBindings.DefaultDataSourceUpdateMode = 0 
48.
$form1.FormBorderStyle = 3 
49.
$form1.Name = "form1" 
50.
$form1.Text = "Status" 
51.
$form1.StartPosition = 1 
52.
$form1.add_Shown($handler_form1_Shown) 
53.
 
54.
$label1.DataBindings.DefaultDataSourceUpdateMode = 0 
55.
$label1.Font = New-Object System.Drawing.Font("Arial",12,1,3,0) 
56.
 
57.
$System_Drawing_Point = New-Object System.Drawing.Point 
58.
$System_Drawing_Point.X = 12 
59.
$System_Drawing_Point.Y = 9 
60.
$label1.Location = $System_Drawing_Point 
61.
$label1.Name = "label1" 
62.
$System_Drawing_Size = New-Object System.Drawing.Size 
63.
$System_Drawing_Size.Height = 41 
64.
$System_Drawing_Size.Width = 301 
65.
$label1.Size = $System_Drawing_Size 
66.
$label1.TabIndex = 0 
67.
$label1.Text = "Umbenennung läuft... Bitte warten." 
68.
$label1.TextAlign = 32 
69.
 
70.
$form1.Controls.Add($label1) 
71.
 
72.
#endregion Generated Form Code 
73.
 
74.
#Save the initial state of the form 
75.
$InitialFormWindowState = $form1.WindowState 
76.
#Init the OnLoad event to correct the initial state of the form 
77.
$form1.add_Load($OnLoadForm_StateCorrection) 
78.
#Show the Form 
79.
$form1.ShowDialog()| Out-Null 
80.
 
81.
} #End Function 
82.
 
83.
#Call the Function 
84.
GenerateForm
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (21)

Frage von Xaero1982 zum Thema Microsoft ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Windows Update
Treiberinstallation durch Windows Update läßt sich nicht verhindern (15)

Frage von liquidbase zum Thema Windows Update ...

DSL, VDSL
Problem mit variernder Internetgeschwindigkeit (12)

Frage von schaurian zum Thema DSL, VDSL ...