Ich versuche, ein Bash-Skript zu schreiben, das eine Funktion enthält. Wenn also eine Datei usw. angegeben .tar
wird .tar.bz2
, .tar.gz
wird tar mit den entsprechenden Schaltern verwendet, um die Datei zu dekomprimieren.
Ich verwende if elif then-Anweisungen, die den Dateinamen testen, um zu sehen, womit er endet, und ich kann ihn nicht mithilfe von Regex-Metazeichen in Übereinstimmung bringen.
Um zu vermeiden, dass das Skript, das ich mit 'test' in der Befehlszeile verwende, ständig neu geschrieben wird, dachte ich, dass die folgende Anweisung funktionieren sollte. Ich habe jede mögliche Kombination von Klammern, Anführungszeichen und Metazeichen ausprobiert und es schlägt immer noch fehl.
test sed-4.2.2.tar.bz2 = tar\.bz2$; echo $?
(this returns 1, false)
Ich bin mir sicher, dass das Problem einfach ist und ich habe überall gesucht, aber ich kann mir nicht vorstellen, wie es geht. Weiß jemand, wie ich das machen kann?
check="^a.*c$";if [[ "abc" =~ $check ]];then echo match;fi
Wir müssen den regulären Ausdruck auf einem Var speichern[[ sed-4.2.2.tar.bz2 == "*tar.bz2" ]]
würde nicht funktionieren.[[ ! foo =~ bar ]]
.-n 1
Parameter nicht und fügt ihn auch nicht automatisch in eine$REPLY
Variable ein. Achtung!Eine Funktion, um dies zu tun
Anderer Hinweis
Als Antwort auf Aquarius Power im obigen Kommentar
We need to store the regex on a var
Die Variable BASH_REMATCH wird gesetzt, nachdem Sie mit dem Ausdruck übereinstimmen, und $ {BASH_REMATCH [n]} stimmt mit der in Klammern eingeschlossenen n-ten Gruppe überein, dh in den folgenden
${BASH_REMATCH[1]} = "compressed"
und${BASH_REMATCH[2]} = ".gz"
(Der obige reguläre Ausdruck ist nicht für die Benennung und Erweiterung von Dateien gültig, funktioniert jedoch für das Beispiel.)
quelle
a
auf GNU tar oderp
auf BSD tar, um explizit anzuweisen, den Komprimierungstyp automatisch aus der Erweiterung abzuleiten. GNU tar wird es sonst nicht automatisch tun, und ich vermute aus @ GoodPersons Kommentar, dass BSD tar dies standardmäßig tut.Ich habe nicht genug Repräsentanten, um hier einen Kommentar abzugeben, daher reiche ich eine neue Antwort ein, um die Antwort von dogbane zu verbessern. Der Punkt . im regulären Ausdruck
[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched
stimmt tatsächlich mit jedem Zeichen überein, nicht nur mit dem Literalpunkt zwischen 'tar.bz2'
oder alles, was es nicht erfordert, mit '\' zu entkommen. Die strenge Syntax sollte dann sein
oder Sie können noch strenger vorgehen und auch den vorherigen Punkt in den regulären Ausdruck aufnehmen:
quelle
Da Sie bash verwenden, müssen Sie dafür keinen untergeordneten Prozess erstellen. Hier ist eine Lösung, die es vollständig innerhalb von Bash ausführt:
Erläuterung: Die Gruppen vor und nach der Sequenz "Doppelpunkt und ein oder mehrere Leerzeichen" werden vom Mustervergleichsoperator im Array BASH_REMATCH gespeichert.
quelle
Funktioniert bei mir!
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
quelle
[[ ... ]]
, ist die rechte Seite glob Muster nicht erweitern das aktuelle Verzeichnis nach tho, wie es normalerweise tun würde.[[...]]
führt Bash keine Dateinamenerweiterung durch. Im Bash-HandbuchWord splitting and filename expansion are not performed on the words between the [[ and ]];
shopt -s nocasematch
quelle