Ich möchte das letzte Zeichen eines Strings löschen, ich habe dieses kleine Skript ausprobiert:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
aber es wird "lkj" ausgegeben, was mache ich falsch?
quelle
Ich möchte das letzte Zeichen eines Strings löschen, ich habe dieses kleine Skript ausprobiert:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
aber es wird "lkj" ausgegeben, was mache ich falsch?
In einer POSIX-Shell ${t:-2}
bedeutet die Syntax etwas anderes - sie wird auf den Wert von t
if t
gesetzt und nicht null und ansonsten auf den Wert erweitert 2
. Wenn Sie ein einzelnes Zeichen durch Parametererweiterung zuschneiden möchten, möchten Sie wahrscheinlich die folgende Syntax verwenden${t%?}
Beachten Sie, dass in ksh93
, bash
oder zsh
, ${t:(-2)}
oder ${t: -2}
(beachten Sie das Leerzeichen) sind als Teil Expansion legal sind aber wahrscheinlich nicht das, was Sie wollen, da sie den Teil beginnend an einer Position 2 Zeichen vom Ende (dh es entfällt die Rück ersten Zeichen i
des Zeichenfolge ijk
).
Weitere Informationen finden Sie im Abschnitt zur Shell-Parametererweiterung im Bash-Referenzhandbuch:
${parameter%word}
entfernt die kürzeste Suffix- Musterübereinstimmungword
- siehe Abschnitt Parametererweiterung vonman bash
Ab
bash
4.2 können Sie:Beispiel:
Beachten Sie, dass Sie bei älteren Versionen
bash
(z. B.bash 3.2.5
unter OS X) Leerzeichen zwischen und nach Doppelpunkten lassen sollten:quelle
bash
Version 4.2-alpha. Schade, dass die Version, auf die ich Zugriff habe, früher ist. : - /${var:offset:lenght}
nur in hinzugefügtbash 4.2
. Vielleicht fügt OSX einen eigenen Patch fürbash
.Zum Entfernen der letzten
n
Zeichen aus einer Zeile, in dersed
OR nicht verwendet wirdawk
:So können Sie beispielsweise das letzte Zeichen folgendermaßen löschen
one character
:von
rev
manpage:AKTUALISIEREN:
Wenn Sie die Länge der Zeichenfolge nicht kennen, versuchen Sie Folgendes:
quelle
Mit sed sollte es so schnell wie möglich sein
Dein einziges Echo ist dann
echo ljk | sed 's/.$//'
.Mit dieser Option kann die einzeilige Zeichenfolge eine beliebige Größe haben.
quelle
Einige Optionen je nach Shell:
t=${t%?}
t=`expr " $t" : ' \(.*\).'`
t=${t[1,-2]}
t=${t:0:-1}
t=${t:0:${#t}-1}
t=${t/%?}
t=${t/~(E).$/}
@ {t=$1} ~~ $t *?
Beachten Sie, dass, obwohl alle das letzte Zeichen entfernen sollen, einige Implementierungen (solche, die keine Multi-Byte-Zeichen unterstützen) stattdessen das letzte Byte entfernen (was wahrscheinlich das letzte Zeichen beschädigen würde, wenn es ein Multi-Byte wäre) ).
Die
expr
Variante geht davon aus,$t
dass nicht mehr als ein Newline-Zeichen endet. Es wird auch ein Exit-Status ungleich Null zurückgegeben, wenn die resultierende Zeichenfolge0
(000
oder sogar-0
mit einigen Implementierungen) endet . Es kann auch zu unerwarteten Ergebnissen kommen, wenn die Zeichenfolge ungültige Zeichen enthält.quelle
t=${t%?}
ist nicht Bourne, aber es ist unwahrscheinlich, dass Sie heutzutage auf eine Bourne-Shell stoßen.${t%?}
funktioniert aber in allen anderen.fish
ist in Arbeit. 2.3.0, das dasstring
eingebaute Programm einführte, wurde zum Zeitpunkt der Fragen und Antworten nicht veröffentlicht. Mit der Version, auf der ich es teste, müssen Siestring replace -r '(?s).\z' '' -- $t
(und ich würde erwarten, dass sie das ändern möchten, sollten sie die Flags ändern, die sie an PCRE übergeben) oder mehr verworrene. Es geht auch schlecht um Newline-Charaktere, und ich weiß, dass sie das auch ändern wollen.Die tragbarste und kürzeste Antwort lautet mit ziemlicher Sicherheit:
${t%?}
Dies funktioniert in bash, sh, ash, dash, busybox / ash, zsh, ksh usw.
Es funktioniert mithilfe der Shell-Parametererweiterung der alten Schule. Insbesondere
%
gibt das an, dass das kleinste übereinstimmende Suffix eines Parameters entfernt werden sollt
, das mit dem Glob-Muster übereinstimmt?
(dh: ein beliebiges Zeichen).Siehe "Kleinstes Suffixmuster entfernen" hier für eine (viel) detailliertere Erklärung und mehr Hintergrundinformationen. Siehe auch die Dokumentation zu Ihrer Shell (zB:)
man bash
unter "Parametererweiterung".Als Randnotiz, wenn Sie stattdessen das erste Zeichen entfernen möchten, würden Sie verwenden
${t#?}
, da#
Übereinstimmungen von der Vorderseite der Zeichenfolge (Präfix) anstelle der Rückseite (Suffix).Erwähnenswert ist auch, dass beide
%
und#
haben%%
und##
Versionen, die die längste Version des angegebenen Musters anstelle der kürzesten entsprechen. Beide${t%%?}
und${t##?}
würden in diesem Fall jedoch dasselbe tun wie ihr einzelner Operator (fügen Sie also nicht das unnütze zusätzliche Zeichen hinzu). Dies liegt daran, dass das angegebene?
Muster nur mit einem einzelnen Zeichen übereinstimmt. Mischen Sie*
mit einigen Nicht-Platzhaltern ein, und die Dinge werden mit%%
und interessanter##
.Das Verstehen von Parametererweiterungen oder zumindest das Wissen über ihre Existenz und das Nachschlagen von Parametern ist unglaublich nützlich, um Shell-Skripte mit vielen verschiedenen Geschmacksrichtungen zu schreiben und zu entschlüsseln. Parameter Erweiterungen sehen oft wie arkane Shell Voodoo für viele Menschen , weil ... na ja ... sie sind arkane Shell Voodoo (obwohl ziemlich gut dokumentiert , wenn Sie für „Parameter Expansion“ suchen wissen). Auf jeden Fall gut im Werkzeuggürtel zu haben, wenn man in einer Muschel steckt.
quelle
Sie erhalten einen Teilstring von 0 bis zur Stringlänge -1. Beachten Sie jedoch, dass diese Subtraktion bash-spezifisch ist und nicht für andere Shells funktioniert.
Kann zum Beispiel
dash
nicht einmal analysierenZum Beispiel unter Ubuntu
/bin/sh
istdash
quelle
Sie können auch verwenden
head
, um alle Zeichen außer dem letzten auszudrucken.Leider enthalten einige Versionen von
head
nicht die führende-
Option. Dies isthead
bei OS X der Fall.quelle
Es ist einfach genug, reguläre Ausdrücke zu verwenden:
quelle
Einige Verfeinerungen. Um mehr als ein Zeichen zu entfernen, können Sie mehrere Fragezeichen hinzufügen. Um beispielsweise die letzten beiden Zeichen aus der Variablen zu entfernen
$SRC_IP_MSG
, können Sie Folgendes verwenden:quelle
Um einige mögliche Verwendungen von purer Bash zu vervollständigen:
Die erste Syntax nimmt einen Teilstring aus einem String, die Syntax ist Für die zweite beachten Sie das Vorzeichen, was "vom Zeilenende" bedeutet und die Syntax ist
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
Und hier sind zwei kürzere Formen der oben genannten
Beachten Sie hier erneut das
%
Zeichen mit der Bedeutung "Entfernen" (dh durch "Ersetzen") des kürzesten übereinstimmenden Musters (hier durch Leerzeichen "\" am Ende des PARAMETERS dargestellt) - hier mit dem Namen " STR"quelle
Da können wir auch PHP in Kommandozeilen- oder Shell-Skripten verwenden. Es ist manchmal nützlich für chirurgisches Parsen.
Mit Rohrleitungen:
quelle
In ksh:
quelle