Suchstring Suche aus CSV Datei mit CMD
Hallo zusammen,
ich habe ein Problem und habe 90% der Lösung bereits hier mit der Suche gefunden.
Die letzten 10% fehlen mir noch
Problem: Ich möchte eine Ordnerstruktur samt Unterordner nach einem exakten Suchstring durchsuchen. Wann immer er eine Datei findet, die auf den Suchstring machted, soll er die Datei in ein Zielverzeichnis kopieren.
Zusatz: Ich möchte den Suchstring nicht nur einmal fix definieren, sondern möchte eine CSV mit Suchstrings bereitstellen. In dieser sind in alle Suchstrings gelistet (immer einer pro Zeile).
Er soll die Suchstrings Zeile für Zeile abarbeiten und jedesmal bei einem Treffer die entsprechende Dateien kopieren. Wenn er die Ordnerstruktur samt Unterordner mit einem String fertig durchsucht hat, holt er sich aus der CSV den nächsten Suchstring.
Das ist mein Script aktuell:
@echo off & setlocal
set "Dateifilter=*MeinSuchString*.pdf"
set "Quelle=C:\RootOrdner"
set "Ziel=C:\Zielordner"
for /f "delims=" %%a in ('dir /s /b /a-d "%Quelle%\%Dateifilter%"') do @(
copy "%%a" "%Ziel%"
)
Wie müsste man meine gewünschte Funktion implementieren? Habe schon rumprobiert aber ohne Erfolg :/
Meine Suchstring CSV Datei sähe so aus:
*MeinSuchString1*.pdf
*MeinSuchString2*.pdf
*MeinSuchString3*.pdf
usw.
ich habe ein Problem und habe 90% der Lösung bereits hier mit der Suche gefunden.
Die letzten 10% fehlen mir noch
Problem: Ich möchte eine Ordnerstruktur samt Unterordner nach einem exakten Suchstring durchsuchen. Wann immer er eine Datei findet, die auf den Suchstring machted, soll er die Datei in ein Zielverzeichnis kopieren.
Zusatz: Ich möchte den Suchstring nicht nur einmal fix definieren, sondern möchte eine CSV mit Suchstrings bereitstellen. In dieser sind in alle Suchstrings gelistet (immer einer pro Zeile).
Er soll die Suchstrings Zeile für Zeile abarbeiten und jedesmal bei einem Treffer die entsprechende Dateien kopieren. Wenn er die Ordnerstruktur samt Unterordner mit einem String fertig durchsucht hat, holt er sich aus der CSV den nächsten Suchstring.
Das ist mein Script aktuell:
@echo off & setlocal
set "Dateifilter=*MeinSuchString*.pdf"
set "Quelle=C:\RootOrdner"
set "Ziel=C:\Zielordner"
for /f "delims=" %%a in ('dir /s /b /a-d "%Quelle%\%Dateifilter%"') do @(
copy "%%a" "%Ziel%"
)
Wie müsste man meine gewünschte Funktion implementieren? Habe schon rumprobiert aber ohne Erfolg :/
Meine Suchstring CSV Datei sähe so aus:
*MeinSuchString1*.pdf
*MeinSuchString2*.pdf
*MeinSuchString3*.pdf
usw.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 502244
Url: https://administrator.de/contentid/502244
Ausgedruckt am: 25.11.2024 um 18:11 Uhr
18 Kommentare
Neuester Kommentar
Moin,
warum einfach, wenn es auch kompliziert geht. Auf der Powershell ist das ein Einzeiler:
Das im Quellordner ausführen und gut ist.
BTW: Das ist keine CSV, sondern eine einfache Textdatei. Eine CSV hat Spaltenüberschriften und Trennzeichen zwischen den Überschriften und den einzelnen Attributen eines Datensatzes.
hth
Erik
warum einfach, wenn es auch kompliziert geht. Auf der Powershell ist das ein Einzeiler:
get-content C:\woauchimmer\suchstrings.txt | %{get-childitem $_ | Copy-Item -Destination c:\zielordner}
Das im Quellordner ausführen und gut ist.
Zitat von @Lupora:
Meine Suchstring CSV Datei sähe so aus:
*MeinSuchString1*.pdf
*MeinSuchString2*.pdf
*MeinSuchString3*.pdf
Meine Suchstring CSV Datei sähe so aus:
*MeinSuchString1*.pdf
*MeinSuchString2*.pdf
*MeinSuchString3*.pdf
BTW: Das ist keine CSV, sondern eine einfache Textdatei. Eine CSV hat Spaltenüberschriften und Trennzeichen zwischen den Überschriften und den einzelnen Attributen eines Datensatzes.
hth
Erik
Hallo @Lupora,
falls es eine Batch-Lösung sein muss, wickele noch eine Schleife drumherum:
Siehe auch mein Tutorial zur FOR-Schleife.
Grüße
Friemler
falls es eine Batch-Lösung sein muss, wickele noch eine Schleife drumherum:
@echo off & setlocal
set "SuchStrings=C:\SuchStrings.txt"
set "Quelle=C:\RootOrdner"
set "Ziel=C:\Zielordner"
for /f "usebackq delims=" %%a in ("%SuchStrings%") do (
for /f "delims=" %%b in ('dir /s /b /a:-d "%Quelle%\%%~a" 2^>NUL') do (
copy "%%~b" "%Ziel%"
)
)
Siehe auch mein Tutorial zur FOR-Schleife.
Grüße
Friemler
Zitat von @erikro:
> get-content C:\woauchimmer\suchstrings.txt | %{get-childitem $_ | Copy-Item -Destination c:\zielordner}
>
Eine Alternative zu der Variante etwas abgewandelt dann ist die Suche mit Get-ChildItem nur ein Aufruf.
Get-ChildItem 'C:\Rootordner\*' -Include (gc 'D:\suchstrings.txt') -File | copy-item -Destination 'C:\zielordner'
Auch in der Batch nutzbar wenn's sein muss
@echo off
powershell -EP Bypass -NoP -C "Get-ChildItem 'C:\Rootordner\*' -Include (gc 'D:\suchstrings.txt') -File | copy-item -Destination 'C:\zielordner'"
Zitat von @Lupora:
Könnte man noch einen Befehl dazu packen, damit er alle gefundenen Bilder (die auf Suchstrings matchen) nicht in einen gemeinsamen Zielordner verschiebt? Sondern das er jeweils einen Ordner angelegt wird mit dem Namen des Suchstrings? Falls Ordner schon vorhanden, kopiert er die gefundenen Dateien da rein. Falls nicht, wird der Ordner erstellt?
Kann man, aber dann muss man auch die Sonderzeichen wie das Sternchen usw. durch entsprechend gültige Zeichen ersetzen, denn sonst lässt sich ein Ordner mit so einem Suchstring erst gar nicht anlegen!Könnte man noch einen Befehl dazu packen, damit er alle gefundenen Bilder (die auf Suchstrings matchen) nicht in einen gemeinsamen Zielordner verschiebt? Sondern das er jeweils einen Ordner angelegt wird mit dem Namen des Suchstrings? Falls Ordner schon vorhanden, kopiert er die gefundenen Dateien da rein. Falls nicht, wird der Ordner erstellt?
gc 'D:\suchstrings.txt' | ?{$_ -notmatch '^\s*$'} | %{
$dest = "c:\zielordner\$($_ -replace '[<>:"/\\|\?\*]','_')"
if(!(Test-Path $dest)){md $dest -force | out-null}
gci "c:\Rootordner\$_" -File | copy-item -Destination $dest
}
Klar
gc 'D:\suchstrings.txt' | ?{$_ -notmatch '^\s*$'} | %{
$files = gci "c:\Rootordner\$_" -File -recurse
if ($files){
$dest = "c:\zielordner\$($_ -replace '[<>:"/\\|\?\*]','_')"
if(!(Test-Path $dest)){md $dest -force | out-null}
$files | copy-item -Destination $dest -Force -verbose
}
}
Nein diese Anforderung hast du nicht erwähnt, dafür musst du im Get-Childitem Befehl den Parameter -recurse setzen. Hab ich dir oben ergänzt.
Das Programm scheint nicht zu starten
Hier geht's einwandfrei. Du machst also was falsch.Die Wildcards habe ich selber gesetzt. Sind die falsch?
Jepp falschBilder*Oktober*2019
Müsste lauten *Bilder*Oktober*2019*
, da ja bei deinen Beispielen am Ende noch andere Strings kommen .*Bilder*
Das ist korrekt und funktioniert auch!Solltest du mal lesen
Supported Wildcards for the Windows File System
Tschö.
Erst mal lesen bevor du nur im dunklen stocherst
Moin Moin,
PS unterstützt alle CMD aspekte, auch "echo"
Es gibt natürlich bessere aspekte, inkl. archivierung in eine csv.
Nur da müßte man wirklich gut sein in PS um das aus dem Ärmel zu schütteln, bin ich nicht,
oder das gesamte Skript sehen und einen Ansatz kriegen.
Auch dann muss Ich es mit viel Arbeit analysieren..
So long
Tom
PS unterstützt alle CMD aspekte, auch "echo"
Es gibt natürlich bessere aspekte, inkl. archivierung in eine csv.
Nur da müßte man wirklich gut sein in PS um das aus dem Ärmel zu schütteln, bin ich nicht,
oder das gesamte Skript sehen und einen Ansatz kriegen.
Auch dann muss Ich es mit viel Arbeit analysieren..
So long
Tom
Moin,
Dafür gibt es die schöne Funktion write-progress.
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell. ...
hth
Erik
Zitat von @Lupora:
Jetzt noch letzte zwei Fragen: Das Script braucht teilweise sehr lange, da ich wirklich gigantische Ordner Mengen habe (> 5k Ordner).
Frage hierzu: Kann ich in der Powershell ein ECHO ausgeben wie bei CMD? Damit ich sehe wo er gerade steht. Ich starte das SCript und 60 Minuten passiert nichts :/ Ich weiß dann nicht, ob er sich aufgehängt hat oder gerade wo hängt. Kann ich die Ausgabe irgendwie sehen?
Jetzt noch letzte zwei Fragen: Das Script braucht teilweise sehr lange, da ich wirklich gigantische Ordner Mengen habe (> 5k Ordner).
Frage hierzu: Kann ich in der Powershell ein ECHO ausgeben wie bei CMD? Damit ich sehe wo er gerade steht. Ich starte das SCript und 60 Minuten passiert nichts :/ Ich weiß dann nicht, ob er sich aufgehängt hat oder gerade wo hängt. Kann ich die Ausgabe irgendwie sehen?
Dafür gibt es die schöne Funktion write-progress.
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell. ...
hth
Erik
Hallo Lupora,
Aufgrund dessen könnte es sinnvoll sein, eine alternative Lösung in Batchscript zu testen. Ich habe in dem Code unten bereits Deinen Zusatzwunsch nach dem Anlegen eines Verzeichnisses, das so benannt ist wie die Suchmaske, integriert. Wenn keine Dateien kopiert wurden, wird das Verzeichnis wieder gelöscht.
Im Abschnitt
Das sollte dann auch Deine Frage von oben beantworten:
Die Datei wird im Kopf der
Grüße
Friemler
Ich starte das Script und 60 Minuten passiert nichts
Aufgrund dessen könnte es sinnvoll sein, eine alternative Lösung in Batchscript zu testen. Ich habe in dem Code unten bereits Deinen Zusatzwunsch nach dem Anlegen eines Verzeichnisses, das so benannt ist wie die Suchmaske, integriert. Wenn keine Dateien kopiert wurden, wird das Verzeichnis wieder gelöscht.
@echo off & setlocal
:: -----------------------------------------------------------------------------
:: Benutzerkonfiguration
:: -----------------------------------------------------------------------------
set "SuchStrings=C:\SuchStrings.txt"
set "Quelle=C:\RootOrdner"
set "Ziel=C:\Zielordner"
:: -----------------------------------------------------------------------------
:: -----------------------------------------------------------------------------
:: Hauptscript
:: -----------------------------------------------------------------------------
set "VBScript=%TEMP%\ReplaceWildcards.vbs"
call :WriteVBScript
for /f "usebackq delims=" %%a in ("%SuchStrings%") do (
call :ProcessSearchTerm "%%~a"
)
del "%VBScript%" 2>NUL
exit /b 0
:: -----------------------------------------------------------------------------
:: Unterprogramme
:: -----------------------------------------------------------------------------
:ProcessSearchTerm
set "SearchTerm=%~1"
set "DirName="
for /f "delims=" %%z in ('cscript /nologo "%VBScript%" "%~1"') do (
set "DirName=%%~z"
)
if "%DirName%" equ "" exit /b 0
md "%Ziel%\%DirName%" 2>NUL
set /a FilesCopied=0
for /f "delims=" %%z in ('dir /s /b /a:-d "%Quelle%\%SearchTerm%" 2^>NUL') do (
copy "%%~z" "%Ziel%\%DirName%"
set /a FilesCopied=1
)
if %FilesCopied% equ 0 (
rd "%Ziel%\%DirName%" 2>NUL
)
exit /b 0
:WriteVBScript
> "%VBScript%" echo strInput = WScript.Arguments(0)
>>"%VBScript%" echo strOutput = Replace(strInput, "*", "_")
>>"%VBScript%" echo strOutput = Replace(strOutput, "?", "_")
>>"%VBScript%" echo WScript.Echo strOutput
exit /b 0
Im Abschnitt
Benutzerkonfiguration
musst Du die Pfade zu Deinen Verzeichnissen und (in Zeile 6) den Pfad zu der Datei mit den Suchstrings eintragen.Das sollte dann auch Deine Frage von oben beantworten:
Enthält dein Code bereits die Liste die hinterlegt werden muss?
Suche in deinem Code die Stelle wo er die Textdatei einliest?
Suche in deinem Code die Stelle wo er die Textdatei einliest?
Die Datei wird im Kopf der
FOR
-Schleife in Zeile 19 eingelesen (in meinem alten Script von weiter oben war es Zeile 7).Grüße
Friemler
Hallo @Lupora,
die
Aber OK, wenn Du eine Ausnahme für führende und angehängte
Was mich noch interessieren würde: Wie lange benötigt mein Batchscript im Vergleich zur PowerShell-Lösung? Um vergleichbare Ergebnisse zu erhalten müsstest Du allerdings zuerst den Befehl
in einem
Grüße
Friemler
die
_
-Zeichen werden dort eingesetzt, wo Dein Suchbegriff Wildcard-Zeichen (also *
oder ?
) enthält, da diese Zeichen für Verzeichnis- bzw. Dateinamen verboten sind.Aber OK, wenn Du eine Ausnahme für führende und angehängte
_
-Zeichen haben möchtest, ersetze das Unterprogramm WriteVBScript
durch folgenden Code::WriteVBScript
> "%VBScript%" echo strInput = WScript.Arguments(0)
>>"%VBScript%" echo strOutput = Replace(strInput, "*", "_")
>>"%VBScript%" echo strOutput = Replace(strOutput, "?", "_")
>>"%VBScript%" echo(
>>"%VBScript%" echo If Left(strOutput, 1) = "_" Then strOutput = Mid(strOutput, 2)
>>"%VBScript%" echo If Right(strOutput, 1) = "_" Then strOutput = Mid(strOutput, 1, Len(strOutput) - 1)
>>"%VBScript%" echo(
>>"%VBScript%" echo WScript.Echo strOutput
exit /b 0
Was mich noch interessieren würde: Wie lange benötigt mein Batchscript im Vergleich zur PowerShell-Lösung? Um vergleichbare Ergebnisse zu erhalten müsstest Du allerdings zuerst den Befehl
dir /s /b /a:-d "Pfad-des-Quellverzeichnisses\*.*"
in einem
CMD.exe
-Fenster ausführen. Dadurch füllt der NTFS-Dateisystemtreiber seinen Cache mit den Daten der zu verarbeitenden Verzeichnisstruktur und sowohl mein Batchscript als auch das PowerShell-Script starten mit den gleichen Voraussetzungen.Grüße
Friemler