PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Regex backreference - das Token ändern



franc
09.03.19, 16:32
Hallo

ich möchte eine winzige Funktion in meine .bashrc einfügen, wo ich einen Parameter übergebe, der ein rename mit RegEx durchführt.
Nämlich in einem Verzeichnis, in dem Untertiteldateien wie etwa: "irgendetwasblabla-S01e01-blabla.srt" stehen, diese auf ein kompaktes S01E01.srt kürzen.
Ich übergebe als Parameter die Endung, weil ich es auch für mp4-Dateien brauche.
Dazu mache ich:


regexsub()
{
rename 's/.*s(\d+)e(\d+).*\.$1/$1$2.$1/'
}

Wie man sieht, beißt sich aber das $1 des Bash-Parameters mit dem Token der Backreferenz (https://www.regular-expressions.info/replacebackref.html).
Zuerst verwende ich das $1 für den Parameter der Bash, dann brauch ich das $1 aber für die Backreferenz (so auch das $2) und schließlich brauch ich wieder den Parameter von der Bash (als Endung, $1).

Kann ich das eine (RegEx-Token) oder andere (Parameter-Token in der Bash) ändern?

Danke, franc

EDIT: vergessener Slash und Hochkomma ergänzt.

marce
09.03.19, 16:47
Ich hab' echt lange gesucht, aber $1 habe ich in keiner Doku für die BackReference gefunden - aber überall \1...

nopes
09.03.19, 17:45
Davon ab, werden Argumente "kopiert", man sollte die aber ohnehin selber umkopieren, damit man nicht verrückt wird ;) kleine online demo - http://tpcg.io/nMSQ2l

karl-heinz-lnx
09.03.19, 19:51
Ich hab' echt lange gesucht, aber $1 habe ich in keiner Doku für die BackReference gefunden - aber überall \1...

Wenn ich mir die Doku zu https://wiki.ubuntuusers.de/rename/ anschaue, passt das schon mit $1 etc..
Aber der Rest ist für mich ziemlich seltsam, so z. B. nur ein Hochkomma und nur 2 Slashes.

franc
09.03.19, 21:05
Davon ab, werden Argumente "kopiert", man sollte die aber ohnehin selber umkopieren, damit man nicht verrückt wird ;) kleine online demo - http://tpcg.io/nMSQ2l
Super! Vielen Dank!

@karl-heinz Ja, das hab beim Abtippen vergessen. Aber nur dort ;) Habs editiert und korrigiert.

franc
10.03.19, 16:35
Davon ab, werden Argumente "kopiert", man sollte die aber ohnehin selber umkopieren, damit man nicht verrückt wird ;) kleine online demo - http://tpcg.io/nMSQ2l

Das geht jetzt. Ich habe nun:



renameext()
{
if [ "$1" = "?" ]
then
echo ""
echo "Benennt SRT/Video-Dateien mit ...SxxEyy...ext um in SxxEyy.ext"
echo "z.B. Tellofix.Saladsauce.S01E05-drink.it.srt -> S01E05.srt"
echo ""
echo "ohne Parameter alle srt-Dateien im aktuellen Verz. (./*.srt)"
echo "mit Parameter (Endung) die Dateien mit der Endung (Parameter: ext)"
echo "z.B.: renameext mp4"
echo "benennt alle mp4-Dateien im aktuellen Verz. um"
echo ""
echo "siehe linuxforen.de post 1853645"
echo ""
return 0
fi

local ext=$1

if [ $# -gt 0 ]
then
rename 's/.*s(\d\d)e(\d\d).*\.${ext}/S$1E$2.${ext}/' ./*.${ext}
else
rename 's/.*s(\d\d)e(\d\d).*\.srt/S$1E$2.srt/' ./*.srt
fi
}
alias renamesub=renameext
alias renamevid=renameext



Allerdings kriege ich wg. der Variablendeklaration eine Warnung (es funktioniert aber):


Global symbol "$ext" requires explicit package name (did you forget to declare "my $ext"?) at (user-supplied code).

nopes
10.03.19, 19:04
Das liegt an dem Quoting, es macht einen Unterschied, ob man dazu ' oder " verwendet. Die Verwendung von ' Quotes bewirkt, dass das dazwischen nicht interpoliert wird, bei " passiert das; Demo - http://tpcg.io/uimKRX

Das erste Argument von rename ist zwischen ' Quotes und daher ein Literal, wird also so uninterpoliert an rename übergeben. Das zweite Argument hat keine Quotes wird also interpoliert, an rename übergeben. Um die Warnung von rename loszuwerden, muss das erste Argument auch interpoliert werden, damit das passiert, muss es zwischen " Quotes stehen, da musst du dann aber auch anders escapen - etwa so:

rename "s/.*s(\\d\\d)e(\\d\\d).*\\.${ext}/S\$1E\$2.${ext}/" ./*.${ext}

Ich rate dir immer " zu nutzen. Eine Art von Quotes reicht aus, die Vorteil der kompakteren Syntax, wiegen die Nachteile nicht auf. Mehr zum Thema:
https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash
http://www.grymoire.com/Unix/Quote.html#TOC

franc
10.03.19, 20:39
Ja, danke!!! Das klappt so. Habe es also auf " umgeändert und dann entsprechend escaped (oder escapet?).
Super, danke für die verständliche Hilfe!

franc
11.03.19, 13:18
Meine Funktion so weit geht so:



renameext()
{
local ext=$1
local rename_files=$2

if [ "$ext" == "help" ]
then
echo "
Benennt Dateien mit ...sxxeyy...ext um in SxxEyy.ext
z.B. Tellofix.Salad.S01E05-eat.it.srt -> S01E05.srt
Gross/Kleinschreibung wird ignoriert (.../i)

Akzeptiert 2 Parameter
Ohne Parameter alle srt-Dateien (mit -NAME.srt zu .NAME.srt) im aktuellen Verz. (./*.srt)

Mit 1. Parameter (Endung) die Dateien mit der Endung (Parameter: ext)
z.B.: renameext mp4
benennt alle mp4-Dateien im aktuellen Verz. um

Mit 2. Parameter (rename_files) = 0 wird nur gezeigt was geaendert wuerde
aber nichts veraendert. Z.B.:
renamesub mp4 0

siehe linuxforen.de post 1853645
"
return 0
fi

if [ $# -eq 0 ]
then
rename "s/.*s(\\d\\d)e(\\d\\d).*\\.${ext}/S\$1E\$2.${ext}/i" ./*.${ext}
elif [ $# -eq 1 ]
then
echo "
Dateien werden umbenannt...
"
rename "s/.*s(\\d\\d)e(\\d\\d).*-(\\w+)\\.srt/S\$1E\$2.\$3.srt/i" ./*.srt
elif [ "$rename_files" == "0" ]
then
echo "
Nichts wird geaendert!
"
rename -n "s/.*s(\\d\\d)e(\\d\\d).*-(\\w+)\\.srt/S\$1E\$2.\$3.srt/i" ./*.srt
fi
}
alias renamesub=renameext
alias renamevid=renameext


Kann man mit Parameter help sehen was sie macht und mit 2. Parameter 0 die Änderungen abschalten und nur anzeigen, was geändert würde.
Klappt :)

franc
19.03.19, 10:55
Das liegt an dem Quoting, es macht einen Unterschied, ob man dazu ' oder " verwendet. ...
Komisch, ich habe es doch auf " Quotes umgestellt und kriege immer noch diesen Fehler.
Ganz reduziert auf die paar Zeilen:


renameext()
{
local ext=$1
rename -v "s/.*s(\\d\\d)e(\\d\\d).*\\.${ext}/S\$1E\$2.\${ext}/i" ./*.${ext}
}
kommt dann bei Eingabe von etwa: renameext srt:


# renameext srt
Global symbol "$ext" requires explicit package name (did you forget to declare "my $ext"?) at (user-supplied code).

Was mache ich da noch falsch? Wie kriege ich diese (Perl-)Warnung weg?

fork
19.03.19, 11:12
Wenn Du das einfache Hochkomma zum Quoting verwendest, dann löst die Shell die Variable nicht auf und es geht als Parameter zum rename-Perl-Script. Das beschwert sich dann darüber, dass es die Variable nicht kennt. (vernünftigerweise hat der Autor des Rename-Scriptes use strict verwendet, denn dadurch wird die Verwendung einer nicht deklarierten Variable sofort moniert).

Verwende doch vor dem Befehl rename mal ein set -x und danach ein set +x, dann siehst Du wie der Befehl vor der Ausführung aussieht. Wenn da das ${ext} noch ohne Variablenersetzung drin steht, dann ist das falsch und kann nur zum Fehler führen.

Beispiel:


renameext()
{
local ext=$1
set -x
rename -v "s/.*s(\\d\\d)e(\\d\\d).*\\.${ext}/S\$1E\$2.\${ext}/i" ./*.${ext}
set +x
}

franc
19.03.19, 13:01
Jetzt verstehe ichs :)
Mit dem set -x wurde es echt deutlich.
Das $ vom ext darf ich natürlich nicht eskapen, also das ist falsch:

rename -v "s/.*s(\\d\\d)e(\\d\\d).*\\.${ext}/S\$1E\$2.\${ext}/i" ./*.${ext}
und das klappt:

rename -v "s/.*s(\\d\\d)e(\\d\\d).*\\.${ext}/S\$1E\$2.${ext}/i" ./*.${ext}
Danke!