In meinem bash
Skript habe ich eine Zeichenfolge und deren Präfix / Suffix. Ich muss das Präfix / Suffix aus der ursprünglichen Zeichenfolge entfernen.
Angenommen, ich habe die folgenden Werte:
string="hello-world"
prefix="hell"
suffix="ld"
Wie komme ich zum folgenden Ergebnis?
result="o-wor"
Antworten:
quelle
${${string#prefix}%suffix}
aber es funktioniert nicht.Mit sed:
Innerhalb des Befehls sed
^
stimmt das Zeichen mit dem Text überein , der mit beginnt$prefix
, und der nachfolgende$
Text stimmt mit dem Text überein, der mit endet$suffix
.Adrian Frühwirth macht einige gute Punkte in den Kommentaren unten, aber
sed
für diesen Zweck kann sehr nützlich sein. Die Tatsache, dass der Inhalt von $ Präfix und $ Suffix von sed interpretiert wird, kann entweder gut oder schlecht sein - solange Sie darauf achten, sollte es Ihnen gut gehen. Das Schöne ist, Sie können so etwas tun:Das ist vielleicht das, was Sie wollen, und es ist sowohl schicker als auch leistungsfähiger als die Substitution von Bash-Variablen. Wenn Sie sich daran erinnern, dass mit großer Kraft große Verantwortung verbunden ist (wie Spiderman sagt), sollte es Ihnen gut gehen.
Eine kurze Einführung in sed finden Sie unter http://evc-cit.info/cit052/sed_tutorial.html
Ein Hinweis zur Shell und zur Verwendung von Strings:
Für das gegebene Beispiel würde auch das Folgende funktionieren:
... aber nur weil:
Es wird im Allgemeinen empfohlen, eine Zeichenfolge in der Befehlszeile in Anführungszeichen zu setzen, da sie dem Befehl auch dann als einzelnes Argument angezeigt wird, wenn sie Leerzeichen enthält. Wir zitieren $ Präfix und $ Suffix aus dem gleichen Grund: Jeder Bearbeitungsbefehl an sed wird als eine Zeichenfolge übergeben. Wir verwenden doppelte Anführungszeichen, weil sie eine variable Interpolation ermöglichen. Hätten wir einfache Anführungszeichen verwendet, hätte der Befehl sed ein Literal erhalten,
$prefix
und$suffix
das ist sicherlich nicht das, was wir wollten.Beachten Sie auch meine Verwendung von einfachen Anführungszeichen beim Festlegen der Variablen
prefix
undsuffix
. Wir möchten sicher nicht, dass irgendetwas in den Zeichenfolgen interpretiert wird, also zitieren wir sie einfach, damit keine Interpolation stattfindet. Auch in diesem Beispiel ist dies möglicherweise nicht erforderlich, aber es ist eine sehr gute Angewohnheit, sich darauf einzulassen.quelle
$string
unterliegt der Aufteilung und dem Globbing von Wörtern. 2)$prefix
und$suffix
kann Ausdrücke enthalten,sed
die interpretiert werden, z. B. reguläre Ausdrücke oder das als Trennzeichen verwendete Zeichen, das den gesamten Befehl unterbricht. 3) Zweimaligessed
Anrufen ist nicht erforderlich (Sie können-e 's///' -e '///'
stattdessen) und die Leitung könnte auch vermieden werden. Betrachten Sie zum Beispielstring='./ *'
und / oderprefix='./'
und sehen Sie, dass es aufgrund von1)
und schrecklich bricht2)
./
, also habe ichsed "s#^$prefix##
stattdessen verwendet. (Fragilität: Dateinamen können nicht enthalten#
. Da ich die Dateien kontrolliere, sind wir dort sicher.)#
als Sed-Trennzeichen bedeutet, dass Sie keine Dateien verarbeiten können, die dieses Zeichen enthalten.Kennen Sie die Länge Ihres Präfixes und Suffixes? In Ihrem Fall:
Oder allgemeiner:
Aber die Lösung von Adrian Frühwirth ist viel cooler! Das wusste ich nicht!
quelle
Ich benutze grep zum Entfernen von Präfixen aus Pfaden (die von nicht gut behandelt werden
sed
):\K
Entfernt alle Zeichen davor aus der Übereinstimmung.quelle
grep -P
ist eine nicht standardmäßige Erweiterung. Mehr Leistung für Sie, wenn es auf Ihrer Plattform unterstützt wird. Dies ist jedoch ein zweifelhafter Rat, wenn Ihr Code einigermaßen portabel sein muss.grep
. Frühere Versionen hatten tatsächlich die-P
Option von BSD,grep
aber sie haben sie entfernt.Anmerkungen:
# $ Präfix: Durch Hinzufügen von # wird sichergestellt, dass der Teilstring "Hölle" nur entfernt wird, wenn er am Anfang gefunden wird. % $ Suffix: Durch Hinzufügen von% wird sichergestellt, dass der Teilstring "ld" nur entfernt wird, wenn er am Ende gefunden wird.
Ohne diese werden die Teilzeichenfolgen "hell" und "ld" überall entfernt, selbst wenn sie sich in der Mitte befinden.
quelle
/
direkt nach der Zeichenfolge. Wozu dient das?Verwenden des
=~
Operators :quelle
Kleine und universelle Lösung:
quelle
expr
. Es war in den Tagen der ursprünglichen Bourne-Hülle eine Art praktisches Spülbecken, ist aber jetzt weit hinter seinem Mindesthaltbarkeitsdatum zurück.Mit @Adrian Frühwirth Antwort:
benutze es so
quelle
Ich würde Capture-Gruppen in Regex verwenden:
((?:(?!(${suffix})).)*)
stellt sicher, dass der Inhalt von${suffix}
aus der Erfassungsgruppe ausgeschlossen wird. In Bezug auf das Beispiel ist es die Zeichenfolge, die äquivalent zu ist[^A-Z]*
. Andernfalls erhalten Sie:quelle