Dalam bash
skrip saya, saya memiliki string dan awalan / sufiksnya. Saya perlu menghapus awalan / akhiran dari string asli.
Misalnya, katakan saya memiliki nilai berikut:
string="hello-world"
prefix="hell"
suffix="ld"
Bagaimana saya mendapatkan hasil berikut?
result="o-wor"
Jawaban:
sumber
${${string#prefix}%suffix}
tetapi tidak berhasil.Menggunakan sed:
Dalam perintah sed,
^
karakter tersebut cocok dengan teks yang dimulai dengan$prefix
, dan$
teks yang cocok dengan yang berakhir dengan$suffix
.Adrian Frühwirth membuat beberapa poin bagus dalam komentar di bawah, tetapi
sed
untuk tujuan ini bisa sangat berguna. Fakta bahwa isi $ awalan dan $ akhiran ditafsirkan oleh sed bisa baik atau buruk - selama Anda memperhatikan, Anda harus baik-baik saja. Keindahannya adalah, Anda dapat melakukan sesuatu seperti ini:yang mungkin apa yang Anda inginkan, dan lebih bagus dan lebih kuat daripada substitusi variabel bash. Jika Anda ingat bahwa dengan kekuatan besar datang tanggung jawab besar (seperti kata Spiderman), Anda harus baik-baik saja.
Pengantar sed yang cepat dapat ditemukan di http://evc-cit.info/cit052/sed_tutorial.html
Catatan tentang shell dan penggunaan string:
Untuk contoh khusus yang diberikan, berikut ini akan berfungsi juga:
... tetapi hanya karena:
Biasanya merupakan praktik yang baik untuk mengutip string pada baris perintah karena meskipun berisi spasi, akan disajikan ke perintah sebagai argumen tunggal. Kami mengutip $ awalan dan $ akhiran untuk alasan yang sama: setiap perintah edit ke sed akan diteruskan sebagai satu string. Kami menggunakan tanda kutip ganda karena mereka memungkinkan interpolasi variabel; seandainya kita menggunakan tanda kutip tunggal perintah sed akan mendapatkan literal
$prefix
dan$suffix
yang jelas bukan yang kita inginkan.Perhatikan juga, saya menggunakan tanda kutip tunggal ketika mengatur variabel
prefix
dansuffix
. Kami tentu saja tidak ingin interpretasi apa pun dalam string, jadi kami mengutipnya sehingga tidak ada interpolasi yang terjadi. Sekali lagi, ini mungkin tidak perlu dalam contoh ini tetapi itu kebiasaan yang sangat baik untuk masuk.sumber
$string
tunduk pada pemisahan kata dan penggumpalan. 2)$prefix
dan$suffix
dapat berisi ekspresi yangsed
akan menafsirkan, misalnya ekspresi reguler atau karakter yang digunakan sebagai pembatas yang akan memecah seluruh perintah. 3) Memanggilsed
dua kali tidak perlu (Anda dapat melakukannya-e 's///' -e '///'
) dan pipa juga bisa dihindari. Sebagai contoh, pertimbangkanstring='./ *'
dan / atauprefix='./'
dan lihat itu rusak parah karena1)
dan2)
./
, jadi saya menggunakansed "s#^$prefix##
, sebagai gantinya. (Kerentanan: nama file tidak dapat mengandung#
. Karena saya mengontrol file, kami aman, di sana.)#
sebagai pembatas sed berarti Anda tidak dapat menangani file yang mengandung karakter itu.Apakah Anda tahu panjang awalan dan akhiran Anda? Dalam kasus Anda:
Atau lebih umum:
Tetapi solusi dari Adrian Frühwirth sangat keren! Saya tidak tahu tentang itu!
sumber
Saya menggunakan grep untuk menghapus awalan dari jalur (yang tidak ditangani dengan baik oleh
sed
):\K
menghapus dari kecocokan semua karakter sebelum itu.sumber
grep -P
adalah ekstensi yang tidak standar. Lebih banyak kekuatan untuk Anda jika didukung pada platform Anda, tetapi ini adalah saran yang meragukan jika kode Anda perlu cukup portabel.grep
. Versi sebelumnya sebenarnya memiliki-P
opsi dari BSDgrep
tetapi mereka menghapusnya.Catatan:
# $ awalan: menambahkan # memastikan bahwa "neraka" substring dihapus hanya jika ditemukan di awal. % $ suffix: menambahkan% memastikan bahwa substring "ld" dihapus hanya jika ditemukan pada akhirnya.
Tanpa ini, substring "neraka" dan "ld" akan dihapus di mana-mana, bahkan ditemukan di tengah.
sumber
/
tepat setelah string, untuk apa itu?Menggunakan
=~
operator :sumber
Solusi kecil dan universal:
sumber
expr
sama sekali. Itu adalah semacam utilitas wastafel dapur yang mudah digunakan pada zaman cangkang Bourne asli, tetapi sekarang sudah melewati tanggal terbaiknya.Menggunakan @Adrian Frühwirth jawaban:
gunakan seperti ini
sumber
Saya akan menggunakan kelompok tangkap di regex:
((?:(?!(${suffix})).)*)
memastikan bahwa konten${suffix}
akan dikecualikan dari grup tangkap. Dalam hal contoh, ini setara dengan string[^A-Z]*
. Kalau tidak, Anda akan mendapatkan:sumber