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?

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/'

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}"

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


20

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

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg

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


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

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

2

Kleine und universelle Lösung:

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

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

expr "|abcdef" : '|*\([^|]*\)|*'

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.