Bash entfernen Sie das erste und letzte Zeichen aus einer Zeichenfolge

99

Ich habe so eine Zeichenfolge:

|abcdefg|

Und ich möchte eine neue Zeichenfolge erhalten, die in irgendeiner Weise (wie string2) mit der ursprünglichen Zeichenfolge ohne die beiden |Zeichen am Anfang und am Ende der Zeichenfolge aufgerufen wird, damit ich Folgendes erhalte :

abcdefg

Ist das in bash möglich?

Matteo Pagliazzi
quelle

Antworten:

121

Du kannst tun

string="|abcdefg|"
string2=${string#"|"}
string2=${string2%"|"}
echo $string2

Oder wenn Ihre String-Länge konstant ist, können Sie dies tun

string="|abcdefg|"
string2=${string:1:7}
echo $string2

Auch das sollte funktionieren

echo "|abcdefg|" | cut -d "|" -f 2

Auch diese

echo "|abcdefg|" | sed 's/^|\(.*\)|$/\1/'
Kris Harper
quelle
2
und auchawk -F\| '{ print $2 }' <<<"|string|"
Enzotib
1
@enzotib Du hast immer coole awkLösungen. Ich muss lernen awk.
Kris Harper
3
und auch IFS='|' read string2 <<< $string:)
arrangiere den
10
und auch in bash 4.2 und neuer"${string:1:-1}"
geirha
Lesen Sie im Abschnitt "Parametererweiterung" nach man bash.
Nemo
62

Hier ist eine Lösung, die unabhängig von der Länge der Zeichenfolge (Bash) ist:

string="|abcdefg|"
echo "${string:1:${#string}-2}"
Samus_
quelle
29

Nach ein paar hier aufgelisteten Beiträgen scheint es der einfachste Weg zu sein, dies zu tun:

string="|abcdefg|"
echo ${string:1:-1}

edit: arbeitet auf Ubuntu mit Bash 4.2; funktioniert nicht unter centOS mit bash 4.1

jlunavtgrad
quelle
20

Eine andere Möglichkeit ist die Verwendung von head& tail-Befehlen:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg
Verhalten
quelle
1
Ich hatte eine Reihe [something something]mit dem Ziel, Klammern zu schneiden, also echo "[something something]" | tail -c +2 | head -c -2klappte es. Danke für einen Tipp!
Ain Tohvri
Natürlich sollte es so sein echo -n "|abcdefg|" | tail -c +2 | head -c -1. Ich bin mir nicht sicher, warum meine Änderungen abgelehnt wurden. Ehrlich gesagt ist das sehr traurig. Siehe man headfür weitere Informationen
Dmitry Khamitov
10

Und noch einer:

string="|abcdefg|"
echo "${string//|/}"
Steven Penny
quelle
9

Sie können auch sed verwenden, um | zu entfernen nicht nur das Symbol selbst referenzieren, sondern Positionsreferenzen wie in:

$ echo "|abcdefg|" | sed 's:^.\(.*\).$:\1:'
abcdefg

Wobei ':' die Begrenzer sind (Sie können sie durch / oder ein beliebiges Zeichen ersetzen, das nicht in der Abfrage enthalten ist. Alle Zeichen, die auf das s folgen, tun dies.) Hier bedeutet ^ (Caret) am Anfang der Eingabezeichenfolge und $ (Dollar) bedeutet Am Ende. Das . (Punkt), dass es nach dem Caret steht und dass es vor dem Dollarzeichen ein einzelnes Zeichen darstellt. Mit anderen Worten, wir löschen das erste und das letzte Zeichen. Beachten Sie, dass dadurch alle Zeichen gelöscht werden, auch wenn | Es ist nicht in der Zeichenfolge vorhanden.

EX:

$ echo "abcdefg" | sed 's:^.\(.*\).$:\1:'
bcdef
Metafaniel
quelle
3

Shell-Funktion

Ein etwas ausführlicherer Ansatz, der jedoch mit allen Arten von ersten und letzten Zeichen funktioniert, muss nicht identisch sein. Die Grundidee ist, dass wir eine Variable nehmen, Zeichen für Zeichen lesen und nur diejenigen anhängen, die wir einer neuen Variablen hinzufügen möchten

Hier ist die ganze Idee in eine nette Funktion formatiert

crop_string_ends() {
    STR="$1" 
    NEWSTR="" 
    COUNT=0 
    while read -n 1 CHAR 
    do
        COUNT=$(($COUNT+1)) 
        if [ $COUNT -eq 1 ] || [ $COUNT -eq ${#STR} ] 
        then
            continue 
        fi 
        NEWSTR="$NEWSTR"$CHAR 
    done <<<"$STR" 
    echo $NEWSTR 
}

Und hier ist die gleiche Funktion in Aktion:

$> crop_string_ends "|abcdefg|"                                                                                       
abcdefg
$> crop_string_ends "HelloWorld"                                                                                      
elloWorl

Python

>>> mystring="|abcdefg|"
>>> print(mystring[1:-1])
abcdefg

oder auf der Kommandozeile:

$ python -c 'import sys;print sys.stdin.read()[1:-2]' <<< "|abcdefg|"                                             
abcdefg

AWK

$ echo "|abcdefg|" | awk '{print substr($0,2,length($0)-2)}'                                                      
abcdefg

Rubin

$ ruby -ne 'print $_.split("|")[1]' <<< "|abcdefg|"                                                               
abcdefg
Sergiy Kolodyazhnyy
quelle
2

Kleine und universelle Lösung:

expr "|abcdef|" : '.\(.*\).'

Besonderes in diesem Fall und damit das '|' Zeichen kann da sein oder nicht:

expr "|abcdef" : '|*\([^|]*\)|*'
Tosi Do
quelle
2
$ string="|abcdefg|"
$ string="${string#?}" && string="${string%%?}"
$ echo "$string"
abcdefg

Von http://tldp.org/LDP/abs/html/parameter-substitution.html

${var#Pattern}
Entfernen Sie aus $vardem kürzesten Teil, der $Patterndem vorderen Ende von entspricht $var. Entfernen Sie aus dem längsten Teil , dass die Spiele hinteren Ende der .
${var%%Pattern}
$var$Pattern$var

Brian
quelle