Zuerst ist es in der Regel besser, seinen Zweck genau zu benennen. Wenn Sie also wissen, dass der String mit einem .rtf
endet, den Sie entfernen möchten, können Sie einfach var2=${var%.rtf}
verwenden. Ein potenziell nützlicher Aspekt dieses Ansatzes ist, dass wenn der String nicht mit .rtf
endet, überhaupt nichts geändert wird; var2
wird eine unveränderte Kopie von var
enthalten.
Wenn Sie einen Dateinamensuffix entfernen möchten, aber nicht genau wissen oder interessieren, was es ist, können Sie var2=${var%.*}
verwenden, um alles ab dem letzten .
zu entfernen. Oder wenn Sie nur alles bis zum ersten .
behalten möchten, können Sie var2=${var%%.*}
verwenden. Diese Optionen haben das gleiche Ergebnis, wenn es nur ein .
im String gibt, aber wenn es mehr als eine geben könnte, können Sie wählen, von welchem Ende des Strings aus gearbeitet werden soll. Wenn andererseits überhaupt kein .
im String vorhanden ist, wird var2
wieder eine unveränderte Kopie von var
sein.
Wenn Sie wirklich immer eine bestimmte Anzahl von Zeichen entfernen möchten, gibt es hier einige Optionen.
Sie haben dies speziell mit bash
markiert, also werden wir mit den Bash-Builtin-Funktionen beginnen. Diejenige, die am längsten funktioniert hat, ist die gleiche Suffix-Entfernungssyntax, die ich oben verwendet habe: Um vier Zeichen zu entfernen, verwenden Sie var2=${var%????}
. Oder um nur vier Zeichen zu entfernen, wenn das erste ein Punkt ist, verwenden Sie var2=${var%.???}
, was ähnlich wie var2=${var%.*}
ist, aber nur den Suffix entfernt, wenn der Teil nach dem Punkt genau drei Zeichen lang ist. Wie Sie sehen, benötigen Sie pro unbekanntes Zeichen, das entfernt wird, ein Fragezeichen, daher wird dieser Ansatz bei größeren Teilzeichenlängen umständlich.
Eine Option in neueren Shell-Versionen ist die Teilzeichenfolgenextraktion: var2=${var:0:${#var}-4}
. Hier können Sie eine beliebige Zahl anstelle der 4
eingeben, um eine andere Anzahl von Zeichen zu entfernen. Das ${#var}
wird durch die Länge des Strings ersetzt, sodass hier tatsächlich gefragt wird, (Länge - 4) Zeichen zu extrahieren und zu behalten, beginnend mit dem ersten (bei Index 0). Mit diesem Ansatz verlieren Sie die Möglichkeit, die Änderung nur dann vorzunehmen, wenn der String zu einem Muster passt. Solange der String mindestens vier Zeichen lang ist, unabhängig von seinem tatsächlichen Wert, enthält die Kopie alles außer den letzten vier Zeichen.
Sie können den Startindex weglassen; es ist standardmäßig auf 0 gesetzt, sodass Sie das einfach auf var2=${var::${#var}-4}
verkürzen können. Tatsächlich erkennen neuere Versionen von Bash (speziell 4+, was bedeutet, dass die mit MacOS mitgelieferte nicht funktioniert) negative Längen als den Index des Zeichens, an dem aufgehört werden soll, und zählen von hinten vom Ende des Strings. In diesen Versionen können Sie also auch den Ausdruck zur Bestimmung der Stringlänge weglassen: var2=${var::-4}
. Diese Interpretation wird auch angewendet, wenn Sie die Stringlänge festlegen, der String jedoch kürzer als vier Zeichen ist, da dann ${#var}-4
negativ wird. Wenn der String beispielsweise drei Zeichen hat, wird ${var:0:${#var}-4}
zu ${var:0:-1}
und entfernt nur das letzte Zeichen.
Wenn Sie tatsächlich nicht Bash, sondern eine andere POSIX-Shell verwenden, wird die muster basierte Suffix-Entfernung mit %
immer noch funktionieren – selbst in der einfachen alten Dash-Shell, in der die indexbasierte Teilzeichenfolgenextraktion nicht funktioniert. Ksh und Zsh unterstützen beide die Teilzeichenfolgenextraktion, erfordern jedoch den expliziten Startindex 0; Zsh unterstützt auch den negativen Endindex, während Ksh den Längenausdruck benötigt. Beachten Sie, dass Zsh standardmäßig Arrays ab 1 indiziert, aber dennoch Strings ab 0 indiziert, wenn Sie diese bash-kompatible Syntax verwenden. Aber Zsh ermöglicht es Ihnen auch, skalare Parameter so zu behandeln, als wären sie Arrays von Zeichen, wodurch Sie eine Teilzeichenfolge mit der Array-Slice-Syntax [start, end]
erstellen können, wobei das Ende inklusiv ist und als negative Zahl angegeben werden kann, die rückwärts vom Ende zählt: var2=$var[1,-5]
.
Statt der Verwendung der integrierten Shell-Parametererweiterung können Sie natürlich ein Dienstprogramm ausführen, um den String zu ändern, und dessen Ausgabe mit Befehlsersetzung erfassen. Es gibt mehrere Befehle, die funktionieren werden; einer davon ist var2=$(sed 's/.\{4\}$//' <<<"$var")
.