Saya ingin menghapus karakter terakhir dari sebuah string, saya mencoba skrip kecil ini:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
tetapi mencetak "lkj", apa yang saya lakukan salah?
sumber
Saya ingin menghapus karakter terakhir dari sebuah string, saya mencoba skrip kecil ini:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
tetapi mencetak "lkj", apa yang saya lakukan salah?
Dalam shell POSIX, sintaksnya ${t:-2}
berarti sesuatu yang berbeda - itu berkembang ke nilai t
jika t
diatur dan bukan nol, dan sebaliknya ke nilai 2
. Untuk memangkas satu karakter dengan ekspansi parameter, sintaks yang mungkin Anda inginkan adalah${t%?}
Perhatikan bahwa dalam ksh93
, bash
atau zsh
, ${t:(-2)}
atau ${t: -2}
(perhatikan spasi) adalah legal sebagai perluasan substring tetapi mungkin bukan yang Anda inginkan, karena mereka mengembalikan substring mulai dari posisi 2 karakter dari akhir (yaitu menghilangkan karakter pertamai
dari string ijk
).
Lihat bagian Perluasan Parameter Shell pada Bash Reference Manual untuk info lebih lanjut:
${parameter%word}
menghapus pencocokan pola sufiks terpendekword
- lihat bagian Ekspansi Parameterman bash
Dengan
bash
4.2 dan di atasnya, Anda dapat melakukan:Contoh:
Perhatikan bahwa untuk yang lebih lama
bash
(misalnya,bash 3.2.5
pada OS X), Anda harus meninggalkan spasi di antara dan setelah titik dua:sumber
bash
versi 4.2-alpha dan di atasnya, sayang sekali versi yang saya akses sebelumnya. : - /${var:offset:lenght}
ditambahkan hanya dalambash 4.2
. Mungkin OSX menambahkan tambalannya sendiribash
.untuk menghapus
n
karakter terakhir dari garis yang tidak menggunakansed
ORawk
:jadi misalnya Anda dapat menghapus karakter terakhir
one character
menggunakan ini:dari
rev
manpage:MEMPERBARUI:
jika Anda tidak tahu panjang tali, coba:
sumber
Menggunakan sed itu harus secepat
Kemudian gema tunggal Anda
echo ljk | sed 's/.$//'
.Dengan menggunakan ini, string 1-line dapat berukuran berapa saja.
sumber
Beberapa opsi tergantung pada shell:
t=${t%?}
t=`expr " $t" : ' \(.*\).'`
t=${t[1,-2]}
t=${t:0:-1}
t=${t:0:${#t}-1}
t=${t/%?}
t=${t/~(E).$/}
@ {t=$1} ~~ $t *?
Perhatikan bahwa sementara semua seharusnya menghapus karakter terakhir , Anda akan menemukan bahwa beberapa implementasi (yang tidak mendukung karakter multi-byte) malah menghapus byte terakhir (sehingga kemungkinan akan merusak karakter terakhir jika multi-byte) ).
The
expr
varian mengasumsikan$t
tidak berakhir di lebih dari satu karakter baris baru. Ini juga akan mengembalikan status keluar non-nol jika string yang dihasilkan berakhir menjadi0
(atau000
atau bahkan-0
dengan beberapa implementasi). Itu juga bisa memberikan hasil yang tidak terduga jika string berisi karakter yang tidak valid.sumber
t=${t%?}
bukan Bourne tetapi Anda tidak akan menemukan shell Bourne saat ini.${t%?}
tidak bekerja di semua yang lain sekalipun.fish
sedang dalam proses. 2.3.0 yang memperkenalkanstring
builtin tidak dirilis pada saat tanya jawab. Dengan versi yang saya uji, Anda perlustring replace -r '(?s).\z' '' -- $t
(dan saya berharap mereka ingin mengubahnya, mereka harus mengubah flag yang mereka berikan ke PCRE) atau yang lebih berbelit-belit. Itu juga berurusan dengan buruk dengan karakter baris baru, dan saya tahu mereka berencana untuk mengubah itu juga.Jawaban yang paling portabel, dan terpendek, hampir pasti:
${t%?}
Ini berfungsi di bash, sh, ash, dash, busybox / ash, zsh, ksh, dll.
Ini bekerja dengan menggunakan ekspansi parameter shell old-school. Secara khusus,
%
menentukan untuk menghapus akhiran pencocokan terkecil dari parametert
yang cocok dengan pola glob?
(yaitu: karakter apa saja).Lihat "Hapus Pola Sufiks Terkecil" di sini untuk penjelasan (lebih banyak) lebih rinci dan lebih banyak latar belakang. Lihat juga dokumen untuk shell Anda (misalnya:) di
man bash
bawah "ekspansi parameter".Sebagai catatan, jika Anda ingin menghapus karakter pertama , Anda akan menggunakan
${t#?}
, karena#
kecocokan dari depan string (awalan) alih-alih dari belakang (akhiran).Juga diperhatikan adalah bahwa kedua
%
dan#
memiliki%%
dan##
versi yang cocok dengan terpanjang versi pola yang diberikan bukannya terpendek. Keduanya${t%%?}
dan${t##?}
akan melakukan hal yang sama sebagai operator tunggal mereka dalam hal ini (jadi jangan tambahkan karakter tambahan yang tidak berguna). Ini karena?
pola yang diberikan hanya cocok dengan satu karakter. Gabungkan*
dengan beberapa non-wildcard dan hal-hal menjadi lebih menarik dengan%%
dan##
.Memahami ekspansi parameter, atau setidaknya mengetahui tentang keberadaannya dan mengetahui cara mencarinya, sangat berguna untuk menulis dan menguraikan skrip shell dari banyak rasa. Ekspansi parameter sering terlihat seperti voodoo shell misterius bagi banyak orang karena ... well ... mereka adalah voodoo shell misterius (meskipun cukup baik didokumentasikan jika Anda tahu untuk mencari "ekspansi parameter"). Pasti bagus untuk ada di sabuk alat saat Anda terjebak dalam cangkang.
sumber
Anda mendapatkan substring dari 0 hingga panjang string -1. Namun perlu dicatat bahwa substraksi ini khusus untuk bash, dan tidak akan berfungsi pada shell lainnya.
Misalnya, bahkan
dash
tidak dapat menguraikanMisalnya, di Ubuntu,
/bin/sh
adalahdash
sumber
Anda juga dapat menggunakan
head
untuk mencetak semua kecuali karakter terakhir.Namun sayangnya beberapa versi
head
tidak menyertakan-
opsi unggulan . Ini adalah kasus untukhead
yang datang dengan OS X.sumber
Cukup mudah dilakukan dengan menggunakan ekspresi reguler:
sumber
Beberapa perbaikan. Untuk menghapus lebih dari satu karakter, Anda dapat menambahkan beberapa tanda tanya. Misalnya, untuk menghapus dua karakter terakhir dari variabel:,
$SRC_IP_MSG
Anda dapat menggunakan:sumber
Hanya untuk melengkapi beberapa kemungkinan penggunaan bash murni:
Sintaks pertama mengambil substring dari string, sintaksnya adalah Untuk yang kedua, perhatikan tanda, yang berarti 'dari ujung garis' dan sintaksnya adalah
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
Dan berikut adalah dua bentuk yang lebih pendek dari yang disebutkan di atas
Di sini perhatikan lagi
%
tanda, yang berarti 'Hapus (yaitu, ganti dengan' ') pola cocok terpendek (di sini diwakili oleh ruang melarikan diri ' \ ' dari ujung PARAMETER - di sini bernama STRsumber
Seperti kita juga bisa menggunakan php di command line, atau skrip shell. Terkadang berguna untuk operasi parsing.
Dengan perpipaan:
sumber
Dalam ksh:
sumber