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
Kommentar vom Moderator Biber am 11.08.2010 um 10:36:49 Uhr
Zitat von 00Snickers:am 11.08.2008
...in U1 liegt. Falls nein, dann move. Falls ja, dann die Datei umbennen in Dateiname + "_" + Inkrement.
Set /a rgc+=1
#696
GELÖST

Batch um Dateien aus Unterordnern in den ersten Unterordner zu verschieben

Frage Entwicklung

Mitglied: 00Snickers

00Snickers (Level 1) - Jetzt verbinden

05.08.2010, aktualisiert 11.08.2010, 6384 Aufrufe, 12 Kommentare

Hallo an alle erst einmal.

Wie sich herrausgestellt hat, habe ich ein etwas komplexeres Problem (zumindest für mich).
In einem Ordner D:\Daten\ befinden sich nach einem automatischen Suchlauf viele verschiedene
Unterordner, deren Namen wie folgt aufgebaut sind: regionaltimes.com aber auch www.dailytimes.com.pk, usw.
In diesen ersten Unterordnern (im Folgenden nur noch U1) können sich zig verschiedene Dateien
und weitere Unterordner beliebiger Tiefe befinden (z.B. D:\Daten\regionaltimes.com\Ordner1\Ordner2\Ordner3\Datei).
Mein Ziel ist es nun, sämtliche Dateien aus den Unterordnern in einem Batchlauf (oder auch mittels VBS) in die
entsprechenden U1 zu verschieben (die leeren Unterordner lösche ich später mit einem extra Batch, das habe ich
bereits gelöst). Leider habe ich bislang keine passende Lösung gefunden, da ein Vorgehen meiner Ansicht
nach ja wie folgt ablaufen müsste:

- öffnen des Ordners D:\Daten\
- Suchlauf durch alle U1, wobei der Ordnername U1 gemerkt werden müsste, da hierher ja später die Dateien
verschoben werden sollen
- U1 und sämtliche Unterordner nach *.* (alle Dateien) durchsuchen und diese dann mit move %1\*.* U1\*.* verschieben

Leider komme ich mit meinen Grundkenntnissen nicht wirklich weiter und habe wie gesagt auch noch nichts
passendes via google-Suche gefunden.
Vll. kann mir ja einer von den Profis hier helfen.
Vielen Dank schon mal im voraus.
Mitglied: bastla
05.08.2010 um 12:55 Uhr
Hallo 00Snickers und willkommen im Forum!

Die Frage bei allen derartigen Vorhaben ist immer: Wie soll bei Namensgleichheit von Dateien vorgegangen werden?

Ansonsten würde sich das (ungetestet) auf etwa
01.
@echo off & setlocal 
02.
set "Basis=D:\Daten" 
03.
 
04.
for /d %%i in ("%Basis%\*.*") do ( 
05.
    pushd "%%i" 
06.
    for /f "delims=" %%a in ('dir /s /b /a-d 2^>nul') do echo move "%%a" 
07.
    popd 
08.
)
reduzieren ...

Das "echo" vor dem "move" soll ein gefahrloses Testen erlauben - ob mehrere gleichnamige Dateien in den Zielordner verschoben (und damit immer die jeweils bereits Vorhandenen überschrieben) würden, lässt sich damit aber nicht feststellen. Nur zur Sicherheit: Ein in einem Batch verwendetes "move" überschreibt ohne Rückfrage (entspricht dem Schalter "/Y")!

Grüße
bastla
Bitte warten ..
Mitglied: Biber
05.08.2010 um 13:11 Uhr
Moin 00Snickers,

willkommen im Forum.
bastla hat sich ja schon der eigentlichen Frage angenommen.

Lass mich noch mal die Sinnhaftigkeit dieses Vorgehens hinterfragen.
Wenn du bisher eine Unterverzeichnisstruktur nach diesem Suchlauf vorliegen hast, dann hast du so oder so nach der Verschieberei einen Informationsverlust

a) weil die Verzeichnisstruktur fehlt und vielleicht einzelne Dateien in den Unterordnern nur in Verbindung mit anderen Dateien in der Unterverzeichnisstruktur interpretierbar sind
b) weil die Wahrscheinlichkeit, dass es keine Dateinamenskollisionen gibt weit unter dem IQ von Paris Hilton liegt. Und da musst diu dich dann zwangsweise von irgendwelchen Originaldaten trennen.

  • Wäre es nicht sinnvoller, die gesammelten Dateien Unterverzeichnisse mit Struktur und allen Dateien zusammenzudampfen mit Rar/Zip/7z/Zoo oder irgendeinem Packprogramm?

  • Und welche der Details deiner Sammelei brauchst du denn überhaupt jemals wieder und WTF wofür?

... irgendwie schimmert der große Plan des ganzen Unterfangens noch nicht so richtig durch.

Grüße
Biber
Bitte warten ..
Mitglied: 00Snickers
05.08.2010 um 14:34 Uhr
Vielen Dank schon mal für die sehr schnelle Hilfe. Werde es gleich mal testen.

Um vll. etwas mehr Licht in die Sache zu bringen: Nach einem Suchlauf werden mit einem Programm
die Inhalte bestimmter Newsseiten gespeichert, daher die komischen Namen der ersten Unterordner.
Diese weisen jedoch je nach Aufbau der Homepage unterschiedliche Tiefen, usw. auf, weshalb die
benötigten Daten entweder direkt im ersten Unterordner oder eben im 20. liegen können. Eine Namensgleichheit
ist ausgeschlossen, da dies beim Speichern im Vorfeld bereits geprüft wird. Zumindest gilt das für diese eine Seite,
ob es bei mehreren der Fall ist wage ich zu bezweifeln, weshalb ich die Dateien ja auch nicht einfach nach
D:\Daten verschieben will, sondern in den jeweiligen Unterordner.

Ich hatte ja auch schon mit den Gedanken gespielt mir einfach die Namen der U1 auszulesen und neue Ordner mittels
md+NameU1+_neu anzulegen, dann die Daten aus allen Unterverzeichnissen dort hinzukopieren und dann die
leeren Ordner zu löschen. Aber 1. reichen da meine Kenntnisse ebenfalls nicht aus und 2. kann mans ja auch einfach
in die ersten Unterordner direkt kopieren.

Die Verzeichnisstruktur ist für mich vollkommen uninteressant. Es sollen zur weiteren vereinfachten Bearbeitung nur die relevanten Dateien direkt im ersten Unterordner zu finden sein und nicht Stunden mit der Suche (Klicken durch zig Ordnerebenen) nach der benötigten Datei (die ich nicht direkt suchen kann, da sowohl Name als auch die Dateiart ständig anders sind) verbracht werden.

Ich hoffe das war verständlich formuliert und es konnte etwas Licht ins Dunkel bringen.
Bitte warten ..
Mitglied: 00Snickers
05.08.2010 um 14:40 Uhr
Was ich noch nicht verstehe ist, was die Eingabe " /a-d^>nul " in der Zeile
for /f "delims=" %%a in ('dir /s /b /a-d 2^>nul') do echo move "%%a" bewirkt.
Vielen Dank.
Bitte warten ..
Mitglied: bastla
05.08.2010 um 16:24 Uhr
Hallo 00Snickers!
Was ich noch nicht verstehe ist, was die Eingabe " /a-d^>nul " ... bewirkt
Ohne die "2" wäre sie kontraproduktiv ...

Der Hilfe zu "dir" (also "dir /?") kannst Du entnehmen, dass mit "/a" bestimmte "Attribute" in das Ergebnis einbezogen / ausgeschlossen werden können - im konkreten Fall interessieren nur Dateien, aber keine "directories" = Ordner, deshalb das Minus.

Mit "2^>nul" werden etwaige Fehlermeldungen (gemeint ist damit vorrangig Datei nicht gefunden) unterdrückt (genauer: ins "Nichts" umgeleitet). Würde anstelle von "2" keine Angabe oder "1" verwendet, hätte das zur Folge, dass die "normalen" Ausgaben / Meldungen (hier also die eigentlich benötigten Pfade zu den Dateien) "verschwinden" würden.

Grüße
bastla
Bitte warten ..
Mitglied: 00Snickers
11.08.2010 um 10:10 Uhr
Die "2" ging mir beim Kopieren wohl irgendwie verschütt

Vielen Dank für die sehr verständliche Erklärung, die mir gleich als Hilfe für ein anderes Problem verhalf
Der Batch funktioniert ebenfalls perfekt und ist genau so wie von mir ursprünglich gedacht!!

ABER nachdem nun schon gefragt wurde zwecks evtl. doppelt vorkommender Dateien (was zwar nicht der
Fall sein sollte bei diesem Problem, aber man weiß ja nie) wurde mein blöder Hang zum Verbessern und
Perfektionieren geweckt Was ich nun bislang erfolglos versuche ist eine Prüfung, ob nicht die Datei mit diesem
Namen bereits in U1 liegt. Falls nein, dann move. Falls ja, dann die Datei umbeNEnnen (man möge mir meinen faux pas bitte verzeihen ) in Dateiname + "_" + Inkrement.

Für eine evtl. Lösung oder Hilfe bin ich sehr dankbar. Sollte ich die Lösung unerwarteterweise doch noch selbst
finden, dann werde ich Sie natürlich hier posten. So oder so markiere ich im Anschluss daran den Post als gelöst.

Viele Grüße
00Snickers
Bitte warten ..
Mitglied: bastla
11.08.2010 um 21:32 Uhr
Hallo 00Snickers!

Kombiniert mit einem Stückchen Code, das ich (ähnlich) schon mal an anderer Stelle verbrochen hatte (und daher gleich mal ungetestet hier einbaue ), könnte das so aussehen:
01.
@echo off & setlocal 
02.
set "Basis=D:\Daten" 
03.
 
04.
for /d %%i in ("%Basis%\*.*") do ( 
05.
    pushd "%%i" 
06.
    for /f "delims=" %%a in ('dir /s /b /a-d 2^>nul') do call :ProcessFile "%%a" 
07.
    popd 
08.
09.
goto :eof 
10.
 
11.
:ProcessFile 
12.
set "N=%~nx1" 
13.
set Nr=1001 
14.
:Loop 
15.
    if not exist "%N%" goto :DoIt 
16.
    set /a Nr+=1 
17.
    set "N=%~n1_%Nr:~-3%%~x1" 
18.
goto :Loop 
19.
:DoIt 
20.
move %1 "%N%" 
21.
goto :eof
Nach dem Motto "Nicht kleckern ..." gibt's die laufende Nummer gleich 3-stellig ...

Sicherung ist hier übrigens keine mehr enthalten - es wird gleich umbenannt (sonst ließen sich ja auch keine gleichnamigen Dateien im Ziel finden ) ...
Plan B wäre übrigens, einfach den gesamten Pfad (durch "Entnahme" der "\") zum Namen zu machen (das Ergebnis wäre aber ziemlich unübersichtlich) ...

Grüße
bastla

P.S.:
man möge mir meinen faux pas bitte verzeihen
Da bist Du nun wirklich nicht der Erste (was Du ja Bibers "running gag counter" entnehmen kannst) ...
Bitte warten ..
Mitglied: 00Snickers
12.08.2010 um 10:36 Uhr
Hallo Bastla,

erneut erstmal vielen Dank.

Hatte ebenfalls mit "IF NOT EXIST" geprüft und dann aber versucht mit "REN" die Dateien umzubenennen.
Ich merke schmerzlich, dass ich einfach viel zu viele Jahre nicht mehr programmiert habe

Die Lösung mit dem Aufruf von Funktionen finde ich da ja mal um Klassen besser als meinen Versuch alles nach dem "DO" reinzupacken. Nachdem ich mich schlau gemacht habe, was die mir unbekannten Teile wie "%~nx1" bewirken habe ich in vollster Vorfreude gleich mal ein paar Testläufe gestartet, aber leider funktioniert das Skript noch nicht bei mir.
Er kopiert nach wie vor alles in den ersten Unterordner (Top!), aber jetzt habe ich in den weiteren Unterordnern einfach Kopien von Dateien erstellt, welche dann z.B. in Test_1, Test_2 umbenannt werden sollten. Jetzt habe ich einfach ein paar "Echo" eingebaut, weil ich sehen wollte, ob er in die Schleife reingeht und die Namen richtig hat, aber mir wird nichts angezeigt.
Hier mein Versuch:

01.
@ECHO OFF & SETLOCAL 
02.
  
03.
SET "Basis=D:\download"  
04.
 
05.
FOR /d %%i IN ("%Basis%\*.*") DO ( 
06.
    PUSHD "%%i"  
07.
    FOR /f "delims=" %%a IN ('dir /s /b /a-d 2^>nul') DO CALL :ProcessFile "%%a" 
08.
    POPD  
09.
10.
GOTO :eof 
11.
 
12.
:ProcessFile  
13.
SET ECHO "FileName=%~nx1"  
14.
SET Counter=1001  
15.
:Loop  
16.
    IF NOT EXIST "%FileName%" GOTO :DoIt  
17.
    SET /a COUNTER+=1  
18.
    SET ECHO "FileName=%~n1_%Counter:~-3%%~x1"  
19.
GOTO :Loop  
20.
:DoIt  
21.
MOVE %1 "%N%"  
22.
GOTO :eof 
Was mir auffiel ist, dass der Aufruf von :Processfile mit der Übergabe von %%a stattfindet, aber die Definition der Funktion ohne Übergabeparameter ist. Spielt das eine Rolle, oder muss man bei der Batchprogrammierung einfach eine Variable übergeben und diese findet sich dann automatisch in der Funktion wieder?

Grüße
00Snickers

P.S. Ja, ich schäme mich immer noch, wo ich doch so viel Wert lege auf korrekte Schreibweise inkl. Groß- und Kleinschreibung...
Bitte warten ..
Mitglied: 00Snickers
12.08.2010 um 10:49 Uhr
Da war ich wohl etwas vorschnell

Hab beim hier reinstellen (m)einen Fehler entdeckt und in Zeile 21. das "%N%" zu "%FileName" gemacht.
Nachdem ich die "ECHO" entfernt habe läufts wunderbar! Ein kleiner Wehrmutstropfen verbleibt allerdings noch:
Befindet sich in dem ersten Unterordner bereits eine Datei, dann lässt er diese nicht einfach stehen, sondern benennt
diese ebenfalls direkt mit "Dateiname" + "_" + "002" um.
Ansonsten bin ich sehr begeistert
Bitte warten ..
Mitglied: bastla
12.08.2010 um 11:16 Uhr
Hallo 00Snickers!

Vorweg kurz zum Unterprogrammaufruf:
Der Teil ab ":ProcessFile" ist im Prinzip ein eigener Batch - deshalb kommen die Aufrufparameter auch als %1, %2, etc an (und benötigen keine eigene Deklaration). Beim zweiten "goto :eof" (entspricht einem "Return" eines [alten] Basic) wird das Unterprogramm beendet und es erfolgt die Rückkehr zum aufrufenden "Hauptprogramm". Das erste "goto :eof" sorgt schließlich für das Ende des Hauptprogrammes (damit nicht das Unterprogramm ein weiteres Mal durchlaufen wird).
Befindet sich in dem ersten Unterordner bereits eine Datei, dann lässt er diese nicht einfach stehen, sondern benennt diese ebenfalls direkt mit "Dateiname" + "_" + "002" um.
Stimmt - das liegt daran, dass ab diesem Unterordner (U1) alle (also auch die bereits unmittelbar in U1 liegenden Dateien) erfasst werden und die Datei "mit sich selbst" kollidieren würde - Abhilfe kann hier nur eine weitere Schleife über alle unter U1 liegenden Ordner schaffen - das müsste dann (weiterhin ungetestet) als neue Zeile 6 (oder, bei Dir, 7) so aussehen:
for /d %%u in (*.*) do for /f "delims=" %%a in ('dir /s /b /a-d "%%u" 2^>nul') do call :ProcessFile "%%a"
Grüße
bastla
Bitte warten ..
Mitglied: 00Snickers
12.08.2010 um 11:28 Uhr
Hallo Bastla!

PERFEKT!!!!

Vielen herzlichen Dank! Funktioniert bestens. Danke für die Geduld und die hilfreichen Erklärungen,
damit kann ich auch allein einige weitere Probleme aufarbeiten. Gibt es hier sowas wie ein Bonuspunktesystem
für perfekte Lösungen? Falls ja, dann vergeb ich diese hiermit an Dich

Vielen Dank und "case closed"

Grüße
00Snickers
Bitte warten ..
Mitglied: bastla
13.08.2010 um 12:21 Uhr
Hallo 00Snickers!

Schön, dass es passt
Gibt es hier sowas wie ein Bonuspunktesystem für perfekte Lösungen? Falls ja, dann vergeb ich diese hiermit an Dich
Gibt es nicht, aber ich freu' mich auch über die "ideellen" Punkte ...

Grüße
bastla
Bitte warten ..
Neuester Wissensbeitrag
Ähnliche Inhalte
Batch & Shell
gelöst Dateien mit Teil des Dateinamen per Batch in Unterordner verschieben (14)

Frage von smitternacht zum Thema Batch & Shell ...

Batch & Shell
gelöst Per Batch Dateien in einen Ordner - ext. Festplatte übertragen (2)

Frage von tocksick zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Userverwaltung
Ausgeschiedene Mitarbeiter im Unternehmen - was tun mit den AD Konten? (33)

Frage von patz223 zum Thema Windows Userverwaltung ...

LAN, WAN, Wireless
FritzBox, zwei Server, verschiedene Netze (21)

Frage von DavidGl zum Thema LAN, WAN, Wireless ...

Viren und Trojaner
Aufgepasst: Neue Ransomware Goldeneye verbreitet sich rasant (20)

Link von Penny.Cilin zum Thema Viren und Trojaner ...