t.unselt
Goto Top

Bash Ergebnis einer Wildcard ausgeben bzw. Speichern

Hallo ihr Lieben,

ich versuche verzweifelt das Ergebnis einer Wildcard bzw Platzhalter auszugeben.
Hier ein Beispiel was ich meine.
Ich hab in einem Dateinamen einen variablen String auf den ich prüfe.

Original Dateiname: Date1nam3MitS03E09VielM1st.kram

Das einzige was immer gleich ist, ist ....S??E??....

Sprich nach dem "S" kommen 2 Ziffern und nach dem "E" kommen 2 Ziffern. Die 4 Platzhalter in dem Fall die Fragezeichen enthalten dann bestimmte Ziffern, die ich in einer Variable oder .txt-Datei brauche. Gerne auch noch mit dem "S" und "E".
Wunschergebnis: S04E07

Ich hoffe ich habe mein Problem genau darstellen können und danke schonmal im Voraus für eure Hilfe!

Mit freundlichen Grüßen
Thorsten

Content-Key: 207357

Url: https://administrator.de/contentid/207357

Printed on: April 23, 2024 at 20:04 o'clock

Member: falscher-sperrstatus
falscher-sperrstatus Jun 02, 2013 at 20:25:41 (UTC)
Goto Top
Hallo Thorsten,

probier es mal per regular expressions. Dürfte dir helfen die Dinge zu vereinfachen.

Grüße
Member: t.unselt
t.unselt Jun 02, 2013 at 20:32:02 (UTC)
Goto Top
Vielen Dank für deine schnelle Antwort.
Ich werde mich gleich ein wenig darüber schlau machen.
Parallel ist mir noch ein weiterer Ansatz eingefallen, der vielleicht helfen könnte.
Wenn ich vor dem S??E?? ein Trennzeichen setzen könnte, könnte ich in der for-schleife mit tokens und delims arbeiten und so den teilstring rausholen.

Gibt es vielleicht eine Möglichkeit mit findstr über "S..E.." Trennzeichen vor oder nach dem Match zu setzen? Oder eine Alternative.

Ich werde mich weiter informieren und bin um jede Hilfe Dankbar.
Member: falscher-sperrstatus
falscher-sperrstatus Jun 02, 2013 at 20:37:17 (UTC)
Goto Top
Hallo,

was ist denn das exakte Ziel?
Mitglied: 64748
64748 Jun 02, 2013 updated at 20:47:54 (UTC)
Goto Top
Guten Abend,

certifiedit hat oben schon richtig gesagt, dass man es mit Regulären Ausdrücken macht. Man muss also ein Werkzeug nehmen, welches solche beherrscht. Ich hab sed genommen. Der gesuchte Code wird zwischen Klammern () die mit Backslash escaped werden müssen "eingefangen", die Variable \1 im Ersetzungsausdruck enthält den eingefangenen Text.

variable=$(find . | sed -n 's/.*\(S[0-9][0-9]E[0-9][0-9]\).*/\1/p')
dann kannst Du Dir mit
echo $variable
den Inhalt der Variablen ansehen.

find durchsucht allerdings im obigen Code auch alle Unterverzeichnisse.

Markus
Member: t.unselt
t.unselt Jun 02, 2013 at 20:45:43 (UTC)
Goto Top
Hi,

Wie bereits oben beschrieben. Ich muss aus einem Dateinamen mit der einzigen Information das der String "S??E??" immer gleich und einmalig ist die beiden Zahlen raus holen. Beide Zahlen haben ein Case von [01-30].

Der Rest des ganzen Dateinamens ist unwichtig. Mir geht es darum im Endeffekt eine Variable mit dem Beispielwert "S03E08" zu haben.

Grüße
Member: falscher-sperrstatus
falscher-sperrstatus Jun 02, 2013 at 20:49:29 (UTC)
Goto Top
Hallo,

@64748: ich bin der Christian ;)

@t.unselt: Was soll denn das Endergebnis sein? Einfaches Dateiumbenennen? Dann mach dir das Leben nicht so schwer. Wie soll das ganze weiterverarbeitet werden, evtl lässt sich dafür eine sinnvollereLösung finden.

Grüße
Member: t.unselt
t.unselt Jun 02, 2013 at 20:55:09 (UTC)
Goto Top
variable=$(find . | sed -n 's/.*\(S[0-9][0-9]E[0-9][0-9]\).*/\1/p')

Hallo Markus. Das sieht sehr vielversprechend aus. Scheinbar habe ich es nicht deutlich gemacht, dass ich mich in einer cmd von Windows bewege.

Entschuldige. Gibt es dazu eine cmd-Analogie?
Member: t.unselt
t.unselt Jun 02, 2013 at 20:57:42 (UTC)
Goto Top
@t.unselt: Was soll denn das Endergebnis sein? Einfaches Dateiumbenennen? Dann mach dir das Leben nicht so schwer. Wie soll das
ganze weiterverarbeitet werden, evtl lässt sich dafür eine sinnvollereLösung finden.

Im prinzip soll die Datei dann nur umbenannt werden.
Meines erachtens benötige ich vorher aber den jeweiligen String aus der Datei "S??E??"

Grüße
Member: falscher-sperrstatus
falscher-sperrstatus Jun 02, 2013 at 20:59:05 (UTC)
Goto Top
Man könnte die Lösung schneller haben, wenn man sagt, was man will. Such mal nach dem Programm reNamer. Das macht das alles für dich.

Grüße
Mitglied: 64748
64748 Jun 02, 2013 at 21:25:52 (UTC)
Goto Top
Zitat von @t.unselt:
Hallo Markus. Das sieht sehr vielversprechend aus. Scheinbar habe ich es nicht deutlich gemacht, dass ich mich in einer cmd von
Windows bewege.

Entschuldige. Gibt es dazu eine cmd-Analogie?
Also der Threadtitel sagt Bash. Ich hab also eine Lösung die unter Unix/Linux in der Shell funktioniert gepostet. Ausprobiert hab ich es allerdings in MobaXterm auf Windows. Wenn Du ein Script brauchst, welches mit Regulären Ausdrücken Dateien umbenennt, dann nimm das hier
#!/usr/bin/perl

use strict ;
use warnings ;
use feature 'say' ;  
use File::Copy ;
 
my ( $old, $new, $in, $op ) ;
$op = shift ;
foreach ( @ARGV ) {
    $old = $_ ;
    eval $op ;
    if ( $old ne $_ && -e $_ ) {
        say "Neuer Dateiname $_ bereits vorhanden. Überspringe $old!" ;  
        next ;
    }
    move ( $old, $_ ) unless $old eq $_ ;
}
das ist ein Perlscript, Perl kannst Du auch auf Windows installieren. Ich benutze das Skript um mp3-Dateien umzubenennen. Bei mir heißt es rename.pl und würde so funktionieren
rename.pl 's/.*(S\d\dE\d\d).*/$1/' *.kram 
Ausgabe:
markus@samsung:~/datei$ touch Date1nam3MitS03E09VielM1st.kram
markus@samsung:~/datei$ ls
Date1nam3MitS03E09VielM1st.kram
markus@samsung:~/datei$ rename.pl 's/.*(S\d\dE\d\d).*/$1/' *.kram 
markus@samsung:~/datei$ ls
S03E09
markus@samsung:~/datei$ 
Das geht auch unter Windows.

Markus
Mitglied: 64748
64748 Jun 02, 2013 at 21:27:41 (UTC)
Goto Top
Zitat von @falscher-sperrstatus:
Hallo,

@64748: ich bin der Christian ;)
Sorry, ich hatte den Namen Thorsten gesehen und den Fehler zu spät bemerkt.

Markus
Member: t.unselt
t.unselt Jun 02, 2013 at 21:46:54 (UTC)
Goto Top
Ich werde es versuchen so deutlich zu schreiben wie möglich.

Ich habe eine Ansammlung von Serien. Die .avi´s liegen meist in Ordnern, welche den Seriennamen, Staffel, Episode und Episodennamen in einer unschönen Form haben. Diese Ordner liegen in eine Überorder z.B Staffel01, Staffel02...
Dieser Ordner liegt wiederum in einem Ordner des Seriennamens, auf dem mein Script angewendet wird.

Die Hierarchie sieht so aus:
J.A.G. - Im Auftrag der Ehre\S03\JAG.S03E04.Die.Sicht.der.Dinge.German.FS.DVDRip.XviD-iNSPiRED\isd-jagdxvid-s03e04.avi

Das Script soll folgendes tun (Anhand dieses Beispiels):
1. Ab "J.A.G. - Im Auftrag der Ehre" alle Unterordner durchsuchen und die AVI´s in einen neuen ORdner kopieren (funktioniert)
2. Im neuen Ordner die jeweilige Staffel und Episode ausfindig machen und die Datei ordentlich Bennen (funktioniert nicht)
So Soll es dann aussehen J.A.G - S03E04

3. Im Besten fall dann noch den Episodennamen " Die SIcht der Dinge" hinten dran hängen. Das ist aber erstmal zweitrangig.

Da ich nicht alle Serien immer mit Serienname.StaffelEpisode.Episodennamen habe, kann ich nicht mit Trennzeichen arbeiten, sondern muss innerhalb des Strings suchen, was es gibt.


Mein bisheriger Code:

FOR /F "delims=#" %%i IN ('dir /ad /b /s /aface-big-smile "%serienpfad%"') DO (
@copy "%%i" %serienpfad%\neu\
echo %%i>%serienpfad%\neu\tmp.txt
findstr "S[0-9][0-9]E[0-9][0-9]" "%serienpfad%\neu\tmp.txt"

)


Grüße
Member: falscher-sperrstatus
falscher-sperrstatus Jun 02, 2013 at 21:50:59 (UTC)
Goto Top
Nimm reNamer, das sollte am schnellsten gehen. Da packst du alle gleich formatierten avis rein und in 2-3 Durchgängen hast du hunderte Daten ordentlich umbenannt.
Member: t.unselt
t.unselt Jun 02, 2013 at 21:56:29 (UTC)
Goto Top
Ich dachte mir schon, dass es darauf hinauslaufen wird.
Es wäre mit Sicherheit die schnellere Lösung. Doch mittlerweile hat mich der Ehrgeiz gepackt und ich will wissen, ob es die CMD wirklich nicht umsetzen kann.

Grüße
Mitglied: 64748
64748 Jun 02, 2013 at 21:57:47 (UTC)
Goto Top
Ich habe mir die Hilfe zu findstr mal angesehen. Das was Du brauchst, nämlich die gefundene Zeichenkette wieder verwenden, das kann findstr nicht. Außerdem ist Batch nicht leistungsfähig genug für so eine Aufgabe.

Entweder Du machst es wie certifiedit schreibt mit dem richtigen Tool, also reNamer (was ich nicht kenne, macht aber nix face-wink). Oder Du bootest mal mit einer Linux-Live-CD und machst es so wie oben beschrieben.

Alternative: benutze eine richtige Programmiersprache unter Windows, z.B. VB.

Markus
Member: Endoro
Endoro Jun 02, 2013 at 23:02:44 (UTC)
Goto Top
Hallo,

Zitat von @64748:
Ich habe mir die Hilfe zu findstr mal angesehen. Das was Du brauchst,
nämlich die gefundene Zeichenkette wieder verwenden, das kann findstr nicht. Außerdem ist Batch nicht
leistungsfähig genug für so eine Aufgabe.

Die erste Aussage stimmt, die zweite nicht face-smile

Wiedemauchsei @Thorsten du solltest mehr live-Dateinamen zum Testen posten. Nicht zwingend erforderlich aber sehr nützlich wäre es, wenn du dir GNU sed für Windows installieren würdest.

Gruss!
Member: t.unselt
t.unselt Jun 02, 2013 at 23:31:45 (UTC)
Goto Top
Hallo Endoro,

vielen Dank für deine späte Antwort. Mitlerweile bin ich das ganze mit powershell am umsetzen.
Ich wollte eigentlich auf zusatztools etc. verzichten. Desshalb ist der renamer auch nichts für mich. Mit dem Sed würde ich mit (find . | sed -n 's/.*\(S[0-9][0-9]E[0-9][0-9]\).*/\1/p') vielleicht an mein Ziel kommen. Aber evtl. finde ich noch einen anderen Weg über cmd eigene Mittel, wo ich ganz anders ansetzen muss.

Grüße.
Member: Endoro
Endoro Jun 03, 2013 updated at 07:06:36 (UTC)
Goto Top
Hallo Thorsten,

hier mal ein Vorschlag für sed + Batch:
@echo off &setlocal
set "videopath=c:\videopath"  
set "destination=c:\new videopath"  
for /f "delims=" %%i in ('dir /s/a-d/b "%videopath%\*.avi"^| findstr /ri "S[0-9][0-9]E[0-9][0-9]"') do (  
	for /f "delims=" %%a in ("%%~dpi.") do set "fdir=%%~nxa"  
	set "fname=%%~fi"  
	for /f "delims=" %%a in ('echo(%%~ni^|sed "s/.*\(S[0-9][0-9]E[0-9][0-9]\).*/\1/i"') do set "nname=%%a"  
	setlocal enabledelayedexpansion
	for /f "tokens=1-6delims=." %%a in ("!fdir!") do set "nname=%%a-!nname!-%%c %%d %%e %%f%%~xi"  
	echo move "!fname!" "%destination%\!nname!"   
	endlocal
)

Gruss!