Bash rimuove il primo e l'ultimo carattere da una stringa


100

Ho una stringa del genere:

|abcdefg|

E voglio ottenere una nuova stringa chiamata in qualche modo (come string2) con la stringa originale senza i due |caratteri all'inizio e alla fine in modo che avrò questo:

abcdefg

È possibile in bash?

Risposte:


121

Tu puoi fare

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

Oppure, se la lunghezza della stringa è costante, puoi farlo

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

Inoltre, dovrebbe funzionare

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

Anche questo

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

2
e ancheawk -F\| '{ print $2 }' <<<"|string|"
enzotib il

1
@enzotib Hai sempre awksoluzioni interessanti. Ho bisogno di imparare awk.
Kris Harper,

3
e anche IFS='|' read string2 <<< $string:)
organizzare il

10
e anche, in bash 4.2 e successivi,"${string:1:-1}"
geirha,

Leggi nella sezione "Espansione dei parametri" in man bash.
Nemo,

63

Ecco una soluzione indipendente dalla lunghezza della stringa (bash):

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

30

Uscendo da alcuni post elencati qui sembra che il modo più semplice per farlo sia:

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

modifica: funziona su Ubuntu con bash 4.2; non funziona su centOS con bash 4.1


21

Un altro modo è usare heade tailcomandi:

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

1
Avevo una corda [something something]con l'obiettivo di tagliare le parentesi, quindi ho echo "[something something]" | tail -c +2 | head -c -2lavorato. Grazie per un suggerimento!
Ain Tohvri,

Ovviamente, dovrebbe essere echo -n "|abcdefg|" | tail -c +2 | head -c -1. Non sono sicuro del motivo per cui le mie modifiche sono state respinte ... È molto triste, a essere sincero. Vedi man headper maggiori informazioni
Dmitry Khamitov il


9

Puoi anche usare sed per rimuovere | non solo facendo riferimento al simbolo stesso ma usando riferimenti posizionali come in:

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

Dove ':' sono i delimitatori (puoi sostituirli con / o qualsiasi carattere non presente nella query, qualsiasi segno che segue lo farà) Qui ^ (cursore) significa all'inizio della stringa di input e $ (dollaro) significa alla fine. Il . (punto) che è dopo il punto di inserimento e quello che è prima del simbolo del dollaro rappresenta un singolo personaggio. Quindi, in altre parole, stiamo eliminando il primo e l'ultimo carattere. Tieni presente che questo eliminerà tutti i caratteri anche se | non è presente nella stringa.

EX:

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

3

funzione shell

Un approccio un po 'più dettagliato, ma funziona su qualsiasi tipo di primo e ultimo carattere, non deve essere lo stesso. L'idea di base è che stiamo prendendo una variabile, leggendola carattere per carattere e aggiungendo solo quelli che vogliamo a una nuova variabile

Ecco l'intera idea formattata in una bella funzione

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 
}

Ed ecco la stessa funzione in azione:

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

Pitone

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

o dalla riga di comando:

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

AWK

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

Rubino

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

2

Soluzione piccola e universale:

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

Speciale in questo caso e permettendo che il '|' il personaggio può essere lì o no:

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

2
$ string="|abcdefg|"
$ string="${string#?}" && string="${string%%?}"
$ echo "$string"
abcdefg

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

${var#Pattern}
Togliere dal $varil più breve parte $Patternche corrisponde alla parte anteriore del $var. Togliere dal la più lunga parte che corrisponde al back-end di .
${var%%Pattern}
$var$Pattern$var

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.