Bash menghapus karakter pertama dan terakhir dari sebuah string

99

Saya memiliki string seperti itu:

|abcdefg|

Dan saya ingin mendapatkan string baru yang disebut someway (seperti string2) dengan string asli tanpa dua |karakter di awal dan di akhir sehingga saya akan memiliki ini:

abcdefg

Apakah itu mungkin di bash?

Matteo Pagliazzi
sumber

Jawaban:

121

Anda dapat melakukan

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

Atau jika panjang string Anda konstan, Anda bisa melakukannya

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

Juga, ini seharusnya berhasil

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

Juga ini

echo "|abcdefg|" | sed 's/^|\(.*\)|$/\1/'
Kris Harper
sumber
2
dan jugaawk -F\| '{ print $2 }' <<<"|string|"
enzotib
1
@enzotib Anda selalu punya awksolusi keren . Saya perlu belajar awk.
Kris Harper
3
dan juga IFS='|' read string2 <<< $string:)
mengatur
10
dan juga, di bash 4.2 dan yang lebih baru,"${string:1:-1}"
geirha
Baca di bawah bagian "ekspansi parameter" di man bash.
Nemo
62

Inilah solusi yang tidak tergantung pada panjang string (bash):

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

Keluar dari beberapa posting yang tercantum di sini tampaknya cara paling sederhana untuk melakukannya adalah:

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

sunting: berfungsi di ubuntu dengan bash 4.2; tidak bekerja pada centOS dengan bash 4.1

jlunavtgrad
sumber
20

Cara lain adalah dengan menggunakan head& tailperintah:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg
Zavior
sumber
1
Saya memiliki serangkaian [something something]tujuan untuk memotong kurung, jadi echo "[something something]" | tail -c +2 | head -c -2berhasil. Terima kasih atas tipnya!
Ain Tohvri
Jelas, seharusnya begitu echo -n "|abcdefg|" | tail -c +2 | head -c -1. Saya tidak yakin mengapa suntingan saya ditolak ... Sangat menyedihkan, jujur ​​saja. Lihat man headuntuk info lebih lanjut
Dmitry Khamitov
10

Dan satu lagi:

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

Anda juga dapat menggunakan sed untuk menghapus | tidak hanya referensi simbol itu sendiri tetapi menggunakan referensi posisi seperti pada:

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

Di mana ':' adalah pembatas (Anda dapat menggantinya dengan / atau karakter apa pun yang tidak ada dalam kueri, tanda apa pun yang mengikuti huruf s akan melakukannya) Di sini ^ (tanda sisipan) berarti pada awal string input dan sarana $ (dolar) berarti pada akhirnya. . (titik) bahwa itu setelah tanda sisipan dan tanda sebelum tanda dolar mewakili satu karakter. Jadi dengan kata lain kita menghapus karakter pertama dan terakhir. Ingat ini akan menghapus karakter apa pun walaupun | itu tidak ada dalam string.

EX:

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

fungsi shell

Pendekatan yang sedikit lebih verbose, tetapi bekerja pada semua jenis karakter pertama dan terakhir, tidak harus sama. Ide dasarnya adalah kita mengambil variabel, membacanya karakter demi karakter, dan menambahkan hanya yang kita inginkan ke variabel baru

Inilah keseluruhan gagasan yang diformat menjadi fungsi yang bagus

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 
}

Dan di sini adalah fungsi yang sama dalam aksi:

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

Python

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

atau di baris perintah:

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

AWK

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

Rubi

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

Solusi kecil dan universal:

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

Istimewa dalam hal ini dan memungkinkan '|' karakter mungkin ada atau tidak:

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

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

${var#Pattern}
Hapus dari $varyang terpendek bagian dari $Patternyang cocok dengan ujung depan dari $var. Hapus dari yang terpanjang bagian dari yang cocok dengan ujung belakang dari .
${var%%Pattern}
$var$Pattern$var

Brian
sumber