TC Such-Kompetenz als cmd-line: Alternative zu DIR gesucht

German support forum

Moderators: Hacker, Stefan2, white

Post Reply
Dauer-TC-ler
Junior Member
Junior Member
Posts: 62
Joined: 2015-03-14, 17:49 UTC

TC Such-Kompetenz als cmd-line: Alternative zu DIR gesucht

Post by *Dauer-TC-ler »

Hallo zusammen!

Im Vergleich zu DIR kann die TC-Suche wesentlich mehr, beispielsweise nach einer beliebigen Zeichenfolge an beliebiger Stelle im Dateinamen suchen. Bei DIR wäre das nur krückenhaft und mit vielen Zeilen und immer mehr Fragezeichen am Anfang machbar (wobei man nach 2 km möglicher Dateinamenlänge keine Lust mehr hat): Zeile 4 hieße da: dir ????xyz*.* >> liste.txt. Außerdem kann die TC-Suche Doubletten finden und so einiges mehr.

Ich suche ein batchfähiges cmd-line-tool mit den Fähigkeiten der TC-Suche, schön viele Parameter usw., so ähnlich wie z.B. robocopy das bessere xcopy ist. Bereits: toolname *xyz*.* wäre genial!

Gibt es sowas hier hausgemacht (quasi "TC-Suche im Handbetrieb"), oder weiß jemand ein bekanntes Tool aus den Tiefen des Web? Oder bleibt da nichts anderes als sich wieder einmal mehr in die weitläufigen Fluten eines neuen FOR-DO-TOKENS-DELIMS - Abenteuer zu stürzen, wofür ich aber Hilfe bräuchte?
User avatar
Dalai
Power Member
Power Member
Posts: 9974
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: TC Such-Kompetenz als cmd-line: Alternative zu DIR gesuc

Post by *Dalai »

Dauer-TC-ler wrote:Im Vergleich zu DIR kann die TC-Suche wesentlich mehr [...]
Nun, das ist ja keine besondere Überraschung, oder? Selbst der Explorer bzw. die Windows-Suche kann mehr als ein simples dir auf einer CMD. Die haben eben ein komplett unterschiedliches Einsatzgebiet.
[...] beispielsweise nach einer beliebigen Zeichenfolge an beliebiger Stelle im Dateinamen suchen.
Das kann jedes Tool, denn Platzhalter (* und ?) funktionieren überall - mal von ganz wenigen Ausnahmen abgesehen.
Bei DIR wäre das nur krückenhaft und mit vielen Zeilen und immer mehr Fragezeichen am Anfang machbar
Warum? Das Sternchen funktioniert schon seit DOS-Zeiten. Falls das auf zuviele Dateinamen passt, dann muss man eben genauere Muster angeben oder ausfiltern (find /V).
Ich suche ein batchfähiges cmd-line-tool mit den Fähigkeiten der TC-Suche, schön viele Parameter usw., so ähnlich wie z.B. robocopy das bessere xcopy ist. Bereits: toolname *xyz*.* wäre genial!
Was willst du denn erreichen? Möglicherweise braucht man gar kein Konsolentool dafür.
Oder bleibt da nichts anderes als sich wieder einmal mehr in die weitläufigen Fluten eines neuen FOR-DO-TOKENS-DELIMS - Abenteuer zu stürzen, wofür ich aber Hilfe bräuchte?
Das sollte kein Problem sein, wenn es denn nötig ist. Aber wie gesagt: vielleicht geht's auch ohne die. (Davon abgesehen wäre wohl PowerShell deutlich mächtiger und besser geeignet.)

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 62
Joined: 2015-03-14, 17:49 UTC

Post by *Dauer-TC-ler »

Danke für die schnelle Antwort, Du hast recht: dir *xyz*.* funktioniert ja doch!

Von irgendwoher (keine Ahnung) hatte ich im Kopf, daß die Wildcard "*" bei DIR nicht am Anfang des Namens geht. Aktuell getestet hatte ich dann mit *=*.*, was in dem Fall ("=") aber eben nicht geht, erst wenn man es so macht: *"="*.* klappt auch das, weil "=" als Sonderzeichen offensichtlich in "" gesetzt werden muß.

Wofür ich das brauche? Ich will Dateien, die ich im Gegensatzt zu den anderen bereits bearbeitet habe, mit originalem Namen im originalem Verzeichnis belassen, sie aber mit einem auffälligen Sonderzeichen markieren, Muster: "Originalname=Bearbeitungart.Suffix", um sie später per cmd gesondert wiederzufinden und in eine Liste auszugeben: *"="*.* > liste.txt. Zur übersichtlichen Kennzeichnung scheint mir das "=" am sympathischsten,
z. B.: Tolle_Sonnen-Blumen=02ce.avi

Nochmals danke für die kalte Dusche zum Munterwerden!

+++++++++++++

Edit,
weil gefragt wurde wofür: Das ganze Projekt ist folgendes (vielleicht ist es ja für den ein oder anderen eine Anregung):

Aufgabe: Per One-Klick in einem (TC-) Verzeichnis (wahlweise inkl. Subs) alle oder nur bestimmete Media-Dateien (z.B solche, die schon bearbeitet wurden, siehe oben) in eine MPC-fähige Playliste ausgeben und sofort starten.

Das Skript dazu, inkl. Anmerkungen am Ende heißt:

++++++++++++++

Code: Select all

echo off

REM bereits bearbeitete Filme wählen
dir *"="*.* /A-D /S /OGN /B > dir.txt

REM alternativ alle Filme wählen
:dir *.avi *.mpg *.wma *.mp4 *.mpeg *.mkv *.wmv *.divx *.mov *.flv *.vob *.asf /A-D /S /OGN /B > dir.txt

REM alle Zeilen nummerieren und dann bei der Ausgabe vor jede Zeile "File" schreiben 
FOR /F "tokens=*" %%A IN ('findstr /N .* "DIR.txt"') DO echo File%%A >> dir.pls
del dir.txt

REM die MPC-Playliste will anstelle des":" aber ein "=":
REM hier speziell für Lw G: gezeigt:

REM Windows 2000
:change3 dir.pls ":g" ":g" "=G"

REM Windows 7
change3 dir.pls ":G" ":G" "=G"

start dir.pls
goto eof
Anmerkungen:

>> dir.pls
Die anghängende Ausgabe ist nötig, weil die FOR-Schleife jede Textzeile einzeln abarbeitet
und diese dann sofort/bzw.jede einzeln an das Ende der Ausgabedatei schreibt.
Deshalb kann die Ausgabedatei auch nicht dieselbe wie die Quelldatei sein.

change läuft nicht in W7, nur change3 (DOS-Tools von Uwe Sieber)

"dir" gibt die Groß-/Kleinschreibung des LW-Buchstabens in W2K und W7 unterschiedlich aus.
Change3 agiert aber case-sensitive.
Deshalb jeweils entsprechend um-aktivieren.
Update: Möglicherweise reagiert das in W7 aber nicht immer logischerweise so? Testen!

Wichtig:
Diese Batch funktioniert für das aktuell gewählte Verzeichnis im TC nur dann, wenn
- Aufruf per TC-ButtonBar (oder manuell)
- bei den ButtonBar-Parametern KEIN Startpfad angegeben ist!
Nur dann wird für die Operationen das AKTUELL gewählte Verzeichnis genommen.

+++++++++++++++
User avatar
Dalai
Power Member
Power Member
Posts: 9974
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Ich weiß nicht, ob man das mit benutzerdef. Kommandos auch automatisiert hinbekommt, ggf. mit Plugins (lst2multi vielleicht?). Problematisch wäre in der Richtung die Ersetzung. Kann MPC nicht auch andere Playlistentypen verarbeiten, die keine Ersetzung brauchen? PLS scheint übrigens einen völlig anderen Aufbau zu haben...

Fakt ist aber, dass dein Skript - wie jedes CMD-Skript ohne besondere Vorkehrungen - bei Pfaden/Dateinamen mit Umlauten versagen wird, weil die CMD diese als ASCII ausgibt, ein deutschsprachiges Windows aber ANSI-codierte Dateinamen benutzt (oder auch Unicode). Dem kann man begegnen, indem man vor der Ausführung der eigentlichen Dateioperationen die Codepage ändert; such mal nach Beiträgen von mir mit "chcp".

Noch ein weiterer Hinweis: dein Suchmuster kannst du auch so angeben:

Code: Select all

"*=*.*"
Das liest sich erheblich besser, als wenn die Anführungszeichen irgendwo im Pattern stehen.

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 62
Joined: 2015-03-14, 17:49 UTC

Post by *Dauer-TC-ler »

Ich weiß nicht, ob man das mit benutzerdef. Kommandos auch automatisiert hinbekommt, ggf. mit Plugins (lst2multi vielleicht?). Problematisch wäre in der Richtung die Ersetzung. Kann MPC nicht auch andere Playlistentypen verarbeiten, die keine Ersetzung brauchen? PLS scheint übrigens einen völlig anderen Aufbau zu haben...
Dieses Skript funktioniert, es ist bereits seit einiger Zeit erfolgreich im Einsatz.
Aufbau einer MPC-pls? Egal was irgendwo als "offiziell" gilt, ich mach sowas ganz einfach:
1. Per MPC eine Playlist erstellen
2. Diese ankucken, wie sie ist
3. per DIR+Param. eine so nachbauen, daß sie dieser am nächsten kommt
4. Die restlichen Unterschiede mit Skript vervollständigen
5. Fertig, passt.

(früher habe ich solche Umbauten per Batch + F&A 4.0-Text-Makro gemacht, ging genauso. F&A noch ein Begriff?)
Fakt ist aber, dass dein Skript - wie jedes CMD-Skript ohne besondere Vorkehrungen - bei Pfaden/Dateinamen mit Umlauten versagen wird, weil die CMD diese als ASCII ausgibt, ein deutschsprachiges Windows aber ANSI-codierte Dateinamen benutzt (oder auch Unicode). Dem kann man begegnen, indem man vor der Ausführung der eigentlichen Dateioperationen die Codepage ändert; such mal nach Beiträgen von mir mit "chcp".
Richtig, gerade getestet, danke für den Hinweis.
Das mit chcp zu richten kenn ich, habe ich bloß hier noch net drangedacht, geht so:

chcp 1252
dir *.* blabla usw.
chcp 850
Noch ein weiterer Hinweis: dein Suchmuster kannst du auch so angeben:Code:
"*=*.*"
Das liest sich erheblich besser, als wenn die Anführungszeichen irgendwo im Pattern stehen.
Nice!

Und weil wir grad so nett dabei sind:
Schreib mir doch bitte mal die rechte FOR-DO-Zeile für diesen Zeichenaustausch, damit ich diese change3 vom Sieber wegkriege. Per FOR-Schleife ist das sicher viel eleganter, aber ich bin da noch net so fit.

Darum gehts: Den ":" vor dem LW-Buchstaben, der noch von der findstr /N - Nummerierung herrührt, mit einem "=" zu ersetzen. die MPC.pls wills halt so, mei, kann i auch nix machn.
Und dann gleich noch den Lw-Buchstaben automatisch mit dem da [%~d0] ermitteln lassen.

Also
:[aktuelles Lw:\Pfad...]
wird zu
=[aktuelles Lw:\Pfad...]

Möglicherweise kann man das sogar noch in die 1. FOR-Schleife bei der Nummerierung (s.o.) mit draufpacken?

wär super!
User avatar
Stefan2
Power Member
Power Member
Posts: 4281
Joined: 2007-09-13, 22:20 UTC
Location: Europa

PowerShell: create PLS play list

Post by *Stefan2 »

Eventuell ist auch Der PowerShell-Weg ein begehbarer?:


Get-ChildItem -Path .\* -include *.avi, *.mpg, *.wma | FOREACH{$OutFile="";$ZAHL=0}  {$ZAHL++;$OutFile+= ("File$ZAHL=""$_""`r`n")}  {$OutFile | Out-File test.pls} ; test.pls

- - -

Kürzer:


Dir .\* -inc *.avi, *.mpg, *.wma|%{$O="";$Z=0}{$Z++;$O+=("File$Z=""$_""`r`n")}{$O|Out-File test.pls} ; test.pls

- - -

Schritt für Schritt:

General Syntax: [face=comicsansms]Get | ForEach {begin} {process} {end}[/face]


# Dir im aktuellen Ornder alle AVI + MPG + WMA:
Get-ChildItem -Path .\* -include *.avi, *.mpg, *.wma

# Für jede gefundene Datei:
  |   FOREACH

# BEGIN (nur einmal) Initializiere Variablen:
{$OutFile="";$ZAHL=0}

# PROCESS (für jede Datei einzeln) erhöhe den Counter
# Schreibe ZAHL + "File=" + vollen Dateinamen in Anführungszeichen + Zeilenendezeichen in die Variable $OutFile:
{$ZAHL++;$OutFile+= ("File$ZAHL=""$_""`r`n")}

# END (nur einmal) gebe den Inhalt der Variable $OutFile aus
# und pipe es an das Kommand Out-File um es in die Datei test.pls zu schreiben:
{$OutFile | Out-File test.pls}

# execute PLS file, if registered with an application:
; test.pls


- - -

Tipp:
Get-ChildItem kennt auch " -recurse"
Out-File kennt auch " -encoding "

https://technet.microsoft.com/en-us/library/hh849958.aspx
http://ss64.com/ps/
 
User avatar
Dalai
Power Member
Power Member
Posts: 9974
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Ich würde das in Batch etwa so machen (erstmal ohne die Umlaut-Berücksichtigung):

Code: Select all

@echo off

REM TC Such-Kompetenz als cmd-line: Alternative zu DIR gesucht
REM http://ghisler.ch/board/viewtopic.php?t=41942

setlocal ENABLEDELAYEDEXPANSION

set count=0

REM bereits bearbeitete Filme wählen
dir "*=*.*" /A-D /S /OGN /B > dir.txt

REM alternativ alle Filme wählen
:dir *.avi *.mpg *.wma *.mp4 *.mpeg *.mkv *.wmv *.divx *.mov *.flv *.vob *.asf /A-D /S /OGN /B > dir.txt

REM alle Zeilen nummerieren und dann bei der Ausgabe vor jede Zeile "File" schreiben
FOR /F "tokens=* delims=" %%A IN (DIR.txt) DO (
    set /a count=!count!+1
    echo File!count!=%%A >> dir.pls
)
del dir.txt
endlocal
start dir.pls
Eigentlich kann man sich noch die Zwischendatei dir.txt sparen, indem man die for-Schleifen schachtelt:

Code: Select all

@echo off

REM TC Such-Kompetenz als cmd-line: Alternative zu DIR gesucht
REM http://ghisler.ch/board/viewtopic.php?t=41942

setlocal ENABLEDELAYEDEXPANSION

set count=0

REM alle Zeilen nummerieren und dann bei der Ausgabe vor jede Zeile "File" schreiben
FOR /F %%F IN ('dir "*=*.*" /A-D /S /OGN /B') DO (
    FOR /F "tokens=* delims=" %%A IN ("%%F") DO (
        set /a count=!count!+1
        echo File!count!=%%A >> dir.pls
    )
)
endlocal
start dir.pls
Aber Stefan2 hat schon recht, wie ich zu Anfang vermutete: PowerShell ist hier deutlich überlegen, auch wenn man sich darin einarbeiten muss, wenn man sie nicht kennt. Ich hab vor einigen Monaten auch mal ein PowerShell-Skript geschrieben und die Sprache für ganz gut befunden, aber schon wieder fast alles vergessen, weil nicht wieder gefordert ;).

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 62
Joined: 2015-03-14, 17:49 UTC

Post by *Dauer-TC-ler »

@Stefan2 + Dalai

Vielen Dank lieber Stefan2 für Deine Mühe. Das glaub ich gerne, daß PowerShell möglicherweise deutlich überlegen ist. Jedoch geht es mir nicht darum, mich übungshalber soviel wie möglich im Handhaben von Skriptsprachen zu betätigen. Dazu habe ich leider einfach keine Zeit und Priorität. Der Vorschlag vom Dalai (siehe unten) tut optimal genau was er soll. Punkt. Warum also sollte ich dem lieben Gott noch einen extra Hut aufsetzen wollen? Damit er schöner wird?

@Dalai

Vielen Dank! Dieses Skript läuft optimal, es ist deutlich schneller als mein altes. Das sind 110%.

Ich habe mich für die 1. Variante entschieden. Warum? Ich zitiere Dich selber:
Noch ein weiterer Hinweis: dein Suchmuster kannst du auch so angeben:Code:
"*=*.*"
Das liest sich erheblich besser, als wenn die Anführungszeichen irgendwo im Pattern stehen.
Ich übersetze für diesen Fall:

Der Abschnitt der DIR-Erstellung ist der DYNAMISCHE Abschnitt, in dem ich in Zukunft viel rumwerkeln werde, um die Ergonomie meiner Wünsche immer wieder zu optimieren, mehrere Startfassungen erstellen usw.
Der 2. Abschnitt "Konvertierung" bleibt dagegen immer gleich, quasi wie ein kleines compiliertes Tool, das nur einfach seinen immer gleichen Job tun soll.

Daher ist es deutlich ergonomischer, den DIR-Part nicht in einen kryptischen Haufen irgendwo dazwischen reinzuquetschen, so daß ich jedesmal umständlich danach suchen muß, von Menü-Erstellung ganz zu schweigen. Es macht in diesem Fall also Sinn, beide Vorgänge getrennt zu behandeln. Den Umstand, die DIR.TXT jedesmal extra löschen zu lassen zu müssen zu sollen, versuche ich deshalb so gut wie möglich zu verkraften ;-)

Nochmal danke für die freundliche und geniale Hilfe,
und anbei nun das "fertige" Skript - optimiert UND: optimierbar(!) für meinen(!) Zweck.

Der Dauer-TC-ler

+++++++++++++++++++++++++++++++

@echo off

REM Teil 1 - flexible und übersichtliche Aufbereitung einer dir.txt, evtl. sogar mit Auswahl-Menü
chcp 1252

REM bereits bearbeitete Medien wählen
:dir "*=*.*" /A-D /S /OGN /B > dir.txt

REM alternativ alle Medien wählen
dir *.avi *.mpg *.wma *.mp4 *.mpeg *.mkv *.wmv *.divx *.mov *.flv *.vob *.asf /A-D /S /OGN /B > dir.txt
dir *.wav *.mp3 *.wma *.ape /A-D /S /OGN /B >> dir.txt

chcp 850
REM Teil 2 - dir.txt in funktionsfähige Playlist konvertieren

setlocal ENABLEDELAYEDEXPANSION
set count=0
FOR /F "tokens=* delims=" %%A IN (DIR.txt) DO (
set /a count=!count!+1
echo File!count!=%%A >> dir.pls
)
del dir.txt
endlocal
start dir.pls

+++++++++++++++++++++++++++++++
User avatar
Dalai
Power Member
Power Member
Posts: 9974
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Wär's dann nicht sinnvoller, die Sache in zwei Skripte aufzusplitten? Sowas in der Richtung:

Code: Select all

@echo off

setlocal
set t=dir.txt
set p=dir.pls

REM Teil 1 - flexible und übersichtliche Aufbereitung einer dir.txt, evtl. sogar mit Auswahl-Menü
chcp 1252

REM bereits bearbeitete Medien wählen
:dir "*=*.*" /A-D /S /OGN /B >> %t%

REM alternativ alle Medien wählen
dir *.avi *.mpg *.wma *.mp4 *.mpeg *.mkv *.wmv *.divx *.mov *.flv *.vob *.asf /A-D /S /OGN /B >> %t%
dir *.wav *.mp3 *.wma *.ape /A-D /S /OGN /B >> %t%

chcp 850

call create_playlist.cmd %t% %p%
del %t%
if exist %p% start %p%
endlocal

Code: Select all

@echo off

REM Teil 2 - dir.txt in funktionsfähige Playlist konvertieren

if "%~2"=="" goto :EOF

setlocal ENABLEDELAYEDEXPANSION
set count=0
FOR /F "tokens=* delims=" %%A IN (%~1) DO (
    set /a count=!count!+1
    echo File!count!=%%A >> "%~2"
)
endlocal
Dann kannst du dich im ersten austoben, und rufst mit call das zweite, das die Erstellung der Playlist aus der Dateiliste übernimmt.

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 62
Joined: 2015-03-14, 17:49 UTC

Post by *Dauer-TC-ler »

Da seh ich jetzt keinen weiteren Sinn drin.

Habe öfter schon Arrangements mit mehreren Batches geschrieben, die sich untereinander mit diversen calls zugewunken habe. Spielerei. Alles in einer Datei und ggfls. entsprechende Sprungmarken, find ich übersichtlicher, eleganter und aufgeräumter: Wenn ich schon die Motorhaube aufmache, dann will ich gefälligst alles sehen und sofort überall drehen können.

Nochmal: Es gibt wesentlich mehr zu tun als den besten Osterhasen der Welt noch ein paar mal umzulackieren...
Post Reply