Datei suchen und nur Datinamen der neusten kopieren
Hi,
also ich bin noch ganz neu hier und stehe schon für mich vor einem großen Problem.
Also es geht darum.
ich möchte das ich eine batch starte und dann dort etwas eingebe. das was ich eingegeben habe, soll dann auf den Laufwerken W: und X: gesucht werden und noch mit dem zusatz"*.txt" versehen werden, so dass alle txt dateien gesucht werden welche mit aaa beginnen.
Danach soll mir der Dateiname der Datei mit dem neusten Speicherdatum ohne das ".txt" in die Zwischenablage kopiert werden.
Also auf meinem Laufwerk sind sagen wir die Dateien:
aaa.txt
aaa_1.txt
aaa_2.txt
aaa_3.txt
aaa_4.txt
aaa_5.txt
bbb.txt
bbb_1.txt
ccc.txt
ccc_1.txt
ccc_2.txt
Dies kann bis zu _99 oder noch höher hochgehen.
also wenn ich aaa eingebe, dann soll er mir praktisch "aaa_5" in die zwischenablage kopieren, weil dies die neuste datei ist.
Im Windows explorer ist dies ganz simpel.
ich würde auf suchen gehen.
als Laufwerke würde ich W: und X: auswählen
als suchwort würde ich einfach "aaa*.txt" einegebn
dann bekomme ich alle Dateien.
Dann würde ich sie nach Datum sortieren und dann von der obersten den Dateinamen ohne das ".txt" kopieren.
Das ist eigentlich schon alles.
Das funktioniert im Explorer per Hand echt super, aber ich dachte mir, dass müsste doch auch per batch möglich sein.
also ich bin noch ganz neu hier und stehe schon für mich vor einem großen Problem.
Also es geht darum.
ich möchte das ich eine batch starte und dann dort etwas eingebe. das was ich eingegeben habe, soll dann auf den Laufwerken W: und X: gesucht werden und noch mit dem zusatz"*.txt" versehen werden, so dass alle txt dateien gesucht werden welche mit aaa beginnen.
Danach soll mir der Dateiname der Datei mit dem neusten Speicherdatum ohne das ".txt" in die Zwischenablage kopiert werden.
Also auf meinem Laufwerk sind sagen wir die Dateien:
aaa.txt
aaa_1.txt
aaa_2.txt
aaa_3.txt
aaa_4.txt
aaa_5.txt
bbb.txt
bbb_1.txt
ccc.txt
ccc_1.txt
ccc_2.txt
Dies kann bis zu _99 oder noch höher hochgehen.
also wenn ich aaa eingebe, dann soll er mir praktisch "aaa_5" in die zwischenablage kopieren, weil dies die neuste datei ist.
Im Windows explorer ist dies ganz simpel.
ich würde auf suchen gehen.
als Laufwerke würde ich W: und X: auswählen
als suchwort würde ich einfach "aaa*.txt" einegebn
dann bekomme ich alle Dateien.
Dann würde ich sie nach Datum sortieren und dann von der obersten den Dateinamen ohne das ".txt" kopieren.
Das ist eigentlich schon alles.
Das funktioniert im Explorer per Hand echt super, aber ich dachte mir, dass müsste doch auch per batch möglich sein.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 74418
Url: https://administrator.de/forum/datei-suchen-und-nur-datinamen-der-neusten-kopieren-74418.html
Ausgedruckt am: 07.04.2025 um 16:04 Uhr
11 Kommentare
Neuester Kommentar
Moin Michael587,
willkommen im Forum.
Realisieren lässt sich der Plan natürlich, aber ganz verstehe ich ihn nicht.
Soll nicht heißen, dass ich nicht helfen will, aber Sinn sollte es schon machen...
Grüße
Biber
willkommen im Forum.
Realisieren lässt sich der Plan natürlich, aber ganz verstehe ich ihn nicht.
- der Part mit dem Laufwerke W: und X: nach der jüngsten "SoUndSo"-Datei durchsuchen ist klar und ist auch eine typische Batch-Aufgabe.
- was ich nicht verstehe I: "wenn ich den Batch starte..." : Wie? Wo? Kontextmenü Explorer? Doppelklick Desktop? Isoliert? Teil eines Gesamt-Prozesses?
- was ich nicht verstehe II: WTF willst Du mit dem "Dateinamen" ohne Pfad/Laufwerksangabe und Endung in der Zwischenablage?????
Soll nicht heißen, dass ich nicht helfen will, aber Sinn sollte es schon machen...
Grüße
Biber
Moin MichaelS87,
ein bisschen mehr habe ich verstanden, aber noch nicht alles:
Sorry für die vielen Rückfragen, aber Bätche funktionieren eben so, dass man/frau vorher alles wissen muss...
Grüße
Biber
ein bisschen mehr habe ich verstanden, aber noch nicht alles:
- wieso können denn die Messreihendatei entweder irgendwo auf W: oder irgendwo auf X: sein?
- sind die nicht immer in einem bestimmten Pfad? Oder haben W: und X gar keine Unterverzeichnisstruktur?
- und Du brauchst nicht nur den Datei-Namen (ohne Endung), sondern auch minimal Laufwerk oder sogar Laufwerk/Pfad, richtig?
Sorry für die vielen Rückfragen, aber Bätche funktionieren eben so, dass man/frau vorher alles wissen muss...
Grüße
Biber
Moin MichaelS87,
bastla hat vorgestern eine Lösung gepostet, die schon fast genau passt. Siehe spezielle Directories mit last modified auflisten.
Die Skizze aus diesem Beitrag:
... diese Skizze müsstest Du nur noch ändern, so dass statt EIN Pfad ("D:\Backup\*_Ext") jetzt zwei FOR-Anweisungen nacheinander ausgeführt werden.
Einmal auf "W:\DeinMessreihenPfad\%suchname%.txt" und einmal auf "X:\DeinesKollegenMessreihenpfad\%suchname%.txt."
Den Suchnamen fragst Du am Anfang ab mit
Statt "sort %temp%\whatever.xyz" kannst Du schreiben:
Das Senden an die Zwischenablage geht leider nur mit Zusatztools.
Eines davon heißt CLIP.exe, stammt vom sympathischen Weltmarktführer höchstselbst (in einem der ResKits, glaub ich) und sendet einen Text an das ClipBoard.
P.S. Ich bin etwas zögerlich mit der Batch-Variante, weil... sinnvoller scheint mir, das alles im Excel-Makro selbst abzufackeln.
Oder dürft ihr den nicht ändern (Kaufprogramm)??
Grüße
Biber
bastla hat vorgestern eine Lösung gepostet, die schon fast genau passt. Siehe spezielle Directories mit last modified auflisten.
Die Skizze aus diesem Beitrag:
@echo off & setlocal
echo.>%temp%\whatever.xyz
for /d %%A in (D:\Backup\*_EXT) do for /f "tokens=1,2,3 delims=. " %%I in ('echo %%~tA') do echo %%K\%%J\%%I %%A >>%temp%\whatever.xyz
sort %temp%\whatever.xyz
Einmal auf "W:\DeinMessreihenPfad\%suchname%.txt" und einmal auf "X:\DeinesKollegenMessreihenpfad\%suchname%.txt."
Den Suchnamen fragst Du am Anfang ab mit
Set /P Suchname="Bitte Dateinamensmuster für die Suche eingeben: "
Statt "sort %temp%\whatever.xyz" kannst Du schreiben:
for /f "tokens=1,2*" %%i in ('sort /R %temp%\whatever.xyz') do Set "NewestName=%%~nj"
Dann hast Du den neuesten Namen in %NewestName%Das Senden an die Zwischenablage geht leider nur mit Zusatztools.
Eines davon heißt CLIP.exe, stammt vom sympathischen Weltmarktführer höchstselbst (in einem der ResKits, glaub ich) und sendet einen Text an das ClipBoard.
P.S. Ich bin etwas zögerlich mit der Batch-Variante, weil... sinnvoller scheint mir, das alles im Excel-Makro selbst abzufackeln.
Oder dürft ihr den nicht ändern (Kaufprogramm)??
Grüße
Biber
ich habe mir schon ein makro geschrieben in excel, das automatisch die benötigten werte aus diesen txt dateien hohlt, wenn ich aaa oder bbb eingebe.
Mal ne ganz doofe Frage:Warum machst du den dann überhaubt den Sprung mit Batch und vba (vom Makro)? Erweitere doch das Makro um die Suchfunktion dann brauchst du mit dem copy&past vom Dateinamen nicht rummachen sondern nur einfach das Makro ausführen?
miniversum
Hallo MichaelS87!
Vielleicht kannst Du ja den folgenden Code Deinen Bedürfnissen anpassen:
Bitte zu beachten, dass die Variablendeklaration der Einfachheit halber im Deklarationsteil des Moduls (vor dem ersten Sub) erfolgt - so stehen diese Variablen ohne Übergabe als Parameter auch im Sub "SearchInFolder" zur Verfügung.
Das Ermitteln der Länge des Suchstrings und das Umwandeln der Suchmaske bzw der Extension in Kleinbuchstaben als Hilfsvariable bereits vor der Such-Schleife sollte (leicht) die Performance verbessern.
Grüße
bastla
Vielleicht kannst Du ja den folgenden Code Deinen Bedürfnissen anpassen:
Dim Suchmaske As String, Ext As String, SuchLen As Integer
Dim Zuletzt As Date, Erg As String
Dim fso As Object
Dim Ordner As Object, Datei As Object, Dateien As Object, Unter As Object
Sub Suchen()
Ext = "txt" 'Typ der zu suchenden Datei
Roots = Array("W:\", "X:\") 'Ordner für Beginn der Suche auf den jeweiligen Laufwerken
'Eingabe Suchmaske
Suchmaske = InputBox("Bitte Anfang des Dateinamens als Suchmaske angeben!", "Suchmaske")
'Hilfsvariable
Suchmaske = LCase(Suchmaske)
SuchLen = Len(Suchmaske)
Ext = LCase(Ext)
Set fso = CreateObject("Scripting.FileSystemObject")
Zuletzt = 0 'Initialisierung Zwischenspeicher für jüngstes Dateidatum
Erg = ""
For Each Root In Roots
Set Ordner = fso.GetFolder(Root) 'Start der Suche mit dem jeweiligem Startordner je Laufwerk
SearchInFolder Ordner
Next
If Erg <> "" Then
'Voller Pfad der jüngsten passenden Datei steht in Erg
Workbooks.Open (Erg)
Else '... oder auch nicht.
MsgBox "Keine zur Suchmaske " & Chr(34) & Suchmaske & "*." & Ext & Chr(34) & _
" passende Datei gefunden!", vbCritical, "Datei nicht gefunden!"
End If
End Sub
Sub SearchInFolder(Ordner)
Set Dateien = Ordner.Files
' Alle Dateien in diesem Ordner abklappern
For Each Datei In Dateien
'Dateityp prüfen
If LCase(fso.GetExtensionName(Datei.Name)) = Ext Then
'Beginnt Dateiname mit Suchmaske?
If LCase(Left(Datei.Name, SuchLen)) = Suchmaske Then
'Änderungsdatum vergleichen ...
If Datei.DateLastModified > Zuletzt Then
'... und wenn neuer, speichern;
Zuletzt = Datei.DateLastModified
Erg = Datei.Path 'Dateipfad natürlich auch ;-)
End If
End If
End If
Next
'Unterordner abklappern, SearchInFolder rekursiv aufrufen
For Each Unter In Ordner.SubFolders
SearchInFolder Unter
Next
End Sub
Das Ermitteln der Länge des Suchstrings und das Umwandeln der Suchmaske bzw der Extension in Kleinbuchstaben als Hilfsvariable bereits vor der Such-Schleife sollte (leicht) die Performance verbessern.
Grüße
bastla
Hallo MichaelS87!
Wenn es tatsächlich genügt, nach dem Änderungsdatum des Ordners zu sortieren, sollte sich das dann nicht ganz so hinziehen. Der Code dafür sähe etwa so aus:
In dieser Fassung wird der gesamte Ordnerpfad in die Zelle A1 der "Tabelle1" geschrieben - soll's wirklich nur der Name sein, dann "Erg = UO.Path" auf "Erg = UO.Name" ändern.
Um das Suchergebnis in die Zwischenablage zu bekommen (geht's denn wirklich nicht anders?) käme die von Dir beschriebene Vorgangsweise oder eine der unter den folgenden Links zu findenden Methoden in Frage:
http://209.85.135.104/search?q=cache:z7BWmbS8JbAJ:mypage.bluewin.ch/rep ...
http://www.aboutvb.de/vba/artikel/vbaclipboard.htm
Grüße
bastla
P.S.: Die "Datei-Such-Variante" hat bei einem Test mit ca 160.000 Dateien bei mir auch knapp 4 Minuten gebraucht (allerdings auf einer lokalen internen SATA-Platte).
[Edit] Den Plan C (Ordnerliste in Batch) können wir ja immer noch versuchen ... [/Edit]
Wenn es tatsächlich genügt, nach dem Änderungsdatum des Ordners zu sortieren, sollte sich das dann nicht ganz so hinziehen. Der Code dafür sähe etwa so aus:
Dim Suchmaske As String, Ext As String, SuchLen As Integer
Dim Zuletzt As Date, Erg As String
Dim fso As Object
Dim Ordner As Object, UO As Object, As Object, Unter As Object
Sub SuchenOrdner()
Roots = Array("W:\", "X:\") 'Ordner für Beginn der Suche auf den jeweiligen Laufwerken
'Eingabe Suchmaske
Suchmaske = InputBox("Bitte Anfang des Ordnernamens angeben!", "Suchmaske")
'Hilfsvariable
Suchmaske = LCase(Suchmaske)
SuchLen = Len(Suchmaske)
Set fso = CreateObject("Scripting.FileSystemObject")
Zuletzt = 0
Erg = ""
For Each Root In Roots
Set Ordner = fso.GetFolder(Root) 'Start der Suche
SearchInFolder Ordner
Next
If Erg <> "" Then
'Voller Pfad der jüngsten passenden Ordners steht in Erg
Worksheets("Tabelle1").Range("A1").Value = Erg
Else '... oder auch nicht.
MsgBox "Keinen zur Suchmaske " & Chr(34) & Suchmaske & "*.*" & Chr(34) & _
" passenden Ordner gefunden!", vbCritical, "Ordner nicht gefunden!"
End If
End Sub
Sub SearchInFolder(Ordner)
' Alle Unterordner überprüfen
For Each UO In Ordner.SubFolders
'Beginnt Ordnername mit Suchmaske?
If LCase(Left(UO.Name, SuchLen)) = Suchmaske Then
'Änderungsdatum vergleichen ...
If UO.DateLastModified > Zuletzt Then
'... und wenn neuer, speichern;
Zuletzt = UO.DateLastModified
'Ordnerpfad natürlich auch
Erg = UO.Path
End If
End If
Next
'Unterordner abklappern, SearchInFolder rekursiv aufrufen
For Each Unter In Ordner.SubFolders
SearchInFolder Unter
Next
End Sub
Um das Suchergebnis in die Zwischenablage zu bekommen (geht's denn wirklich nicht anders?) käme die von Dir beschriebene Vorgangsweise oder eine der unter den folgenden Links zu findenden Methoden in Frage:
http://209.85.135.104/search?q=cache:z7BWmbS8JbAJ:mypage.bluewin.ch/rep ...
http://www.aboutvb.de/vba/artikel/vbaclipboard.htm
Grüße
bastla
P.S.: Die "Datei-Such-Variante" hat bei einem Test mit ca 160.000 Dateien bei mir auch knapp 4 Minuten gebraucht (allerdings auf einer lokalen internen SATA-Platte).
[Edit] Den Plan C (Ordnerliste in Batch) können wir ja immer noch versuchen ... [/Edit]
Hallo MichaelS87!
Soferne die Nummerierung tatsächlich ausreichend ist, um den jüngsten Ordner / die jüngste Datei zu finden (und es nur eine Ordnerebene unterhalb von "W:\m1", etc gibt), müsste es so gehen:
Hoffentlich empfindest Du es nicht als Zwangsbeglückung, wenn Du als Ergebnis nicht die gesamte Liste, sondern nur einen Eintrag (im CMD-Fenster sowie in "C:\Neueste.txt") erhältst
.
Ganz wohl fühle ich mich allerdings mit der Strategie "nach Ordnernamen sortieren" nicht:
Wenn Du keine einheitliche Namenskonvention verwendest, geht das nämlich mit 2- oder mehrstelligen Nummern schief, da eine Textsortierung verwendet wird und daher zB gilt: "aaa_12.txt" < "aaa_2.txt". Die angesprochene Konvention müsste lauten: "Die Nummern aller Ordner-/Dateinamen weisen die gleiche Stellenanzahl auf." Im oben genannten Beispiel würde dies bedeuten, dass als Name "aaa_02" (oder als Vorsorge für dreistellige Nummern "aaa_002") zu verwenden wäre.
Grüße
bastla
[Edit] Delimiter "§" durch "$" ersetzt, da "§" > "_" und "$" < "_", was bei Verwendung von "§" und fehlendem "_" im Ordnernamen zu falscher Sortierung führte) [/Edit]
Soferne die Nummerierung tatsächlich ausreichend ist, um den jüngsten Ordner / die jüngste Datei zu finden (und es nur eine Ordnerebene unterhalb von "W:\m1", etc gibt), müsste es so gehen:
@echo off & setlocal
set "Start=W:\m1 W:\m2 W:\m3 W:\m4 X:\m1"
set "Neueste=C:\Neueste.txt"
set "List=%temp%\whatever.xyz"
set /p "Maske=Bitte Suchmaske eingeben: "
echo.
echo.
if exist "%List%" del "%List%"
if exist "%Neueste%" del "%Neueste%"
for %%S in (%Start%) do for /f "delims=" %%A in ('dir /b /ad "%%S\%Maske%*.*" 2^>nul') do echo %%~nA$%%~fA >>"%List%"
set Neu=
if exist "%List%" (
for /f "tokens=2 delims=$" %%N in ('sort "%List%"') do set "Neu=%%N"
del "%List%"
)
if defined Neu (
echo %Neu%
echo %Neu% >"%Neueste%"
) else (
echo [%Maske%] nicht gefunden!
echo.
pause
)
Ganz wohl fühle ich mich allerdings mit der Strategie "nach Ordnernamen sortieren" nicht:
Wenn Du keine einheitliche Namenskonvention verwendest, geht das nämlich mit 2- oder mehrstelligen Nummern schief, da eine Textsortierung verwendet wird und daher zB gilt: "aaa_12.txt" < "aaa_2.txt". Die angesprochene Konvention müsste lauten: "Die Nummern aller Ordner-/Dateinamen weisen die gleiche Stellenanzahl auf." Im oben genannten Beispiel würde dies bedeuten, dass als Name "aaa_02" (oder als Vorsorge für dreistellige Nummern "aaa_002") zu verwenden wäre.
Grüße
bastla
[Edit] Delimiter "§" durch "$" ersetzt, da "§" > "_" und "$" < "_", was bei Verwendung von "§" und fehlendem "_" im Ordnernamen zu falscher Sortierung führte) [/Edit]
Moin bastla.
eine Code-Verschlankung schlage ich noch vor.
Statt der beiden hintereinandergeschalteten FOR-Anweisungen einfacher:
denn der DIR-Befehl lann ja durchaus mehrere Datei/Pfadangaben in einer Zeile verwerten.
Grüße
Biber
eine Code-Verschlankung schlage ich noch vor.
Statt der beiden hintereinandergeschalteten FOR-Anweisungen einfacher:
...
@echo off & setlocal EnableDelayedExpansion
set "Start=W:\m1\# W:\m2\# W:\m3\# W:\m4\# X:\m1\#"
....
for /f "delims=" %%A in ('dir /b /ad "!Start:#=%Maske%*.*" 2^>nul') do echo %%~nA§%%~fA >>"%List%"
...
...
Grüße
Biber