Saya ingin memeriksa apakah sebuah string dimulai dengan "simpul" mis. "Simpul001". Sesuatu seperti
if [ $HOST == user* ]
then
echo yes
fi
Bagaimana saya bisa melakukannya dengan benar?
Saya selanjutnya perlu menggabungkan ekspresi untuk memeriksa apakah HOST adalah "user1" atau dimulai dengan "node"
if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi
> > > -bash: [: too many arguments
Bagaimana saya bisa melakukannya dengan benar?
string
bash
comparison
Tim
sumber
sumber
Jawaban:
Cuplikan pada Panduan Skrip Bash Lanjutan ini mengatakan:
Jadi Anda sudah hampir benar; Anda membutuhkan tanda kurung ganda , bukan tanda kurung tunggal.
Sehubungan dengan pertanyaan kedua Anda, Anda dapat menuliskannya dengan cara ini:
Yang akan bergema
if
Sintaks Bash sulit digunakan (IMO).sumber
[[ $a == z* ]]
dan[[ $a == "z*" ]]
? Dengan kata lain: apakah mereka bekerja secara berbeda? Dan apa yang Anda maksud ketika Anda mengatakan "$ a sama dengan z *"?[[ $a == *com ]]
Jika Anda menggunakan versi terbaru dari Bash (v3 +), saya sarankan operator perbandingan regex Bash
=~
, misalnya,Untuk mencocokkan
this or that
dalam suatu regex, gunakan|
, misalnya,Catatan - ini adalah sintaks ekspresi reguler 'tepat'.
user*
berartiuse
dan nol atau lebih kejadianr
, jadiuse
danuserrrr
akan cocok.user.*
berartiuser
dan nol atau lebih kemunculan karakter apa pun, jadiuser1
,userX
akan cocok.^user.*
berarti cocok dengan polauser.*
di awal $ HOST.Jika Anda tidak terbiasa dengan sintaks ekspresi reguler, coba rujuk ke sumber ini .
sumber
=~
operator Bash hanya melakukan pencocokan ekspresi reguler ketika sisi kanan UNQUOTED. Jika Anda mengutip sisi kanan, "Bagian mana pun dari pola dapat dikutip untuk memaksa agar dicocokkan dengan string." (1.) pastikan untuk selalu menempatkan ekspresi reguler di sebelah kanan yang tidak dikutip dan (2.) jika Anda menyimpan ekspresi reguler Anda dalam sebuah variabel, pastikan untuk TIDAK mengutip sisi kanan ketika Anda melakukan ekspansi parameter.Saya selalu mencoba untuk tetap dengan POSIX
sh
daripada menggunakan ekstensi Bash, karena salah satu poin utama dari scripting adalah portabilitas (selain menghubungkan program, bukan menggantinya).Di
sh
, ada cara mudah untuk memeriksa kondisi "is-prefix".Mengingat seberapa tua, misterius, dan kekasaran (dan Bash bukan obatnya: Ini lebih rumit, kurang konsisten, dan kurang portabel), saya ingin menunjukkan aspek fungsional yang sangat bagus: Sementara beberapa elemen sintaksis seperti
case
sudah ada di dalamnya , konstruksi yang dihasilkan tidak berbeda dari pekerjaan lain. Mereka dapat disusun dengan cara yang sama:Atau bahkan lebih pendek
Atau bahkan lebih pendek (hanya untuk menyajikan
!
sebagai elemen bahasa - tetapi ini adalah gaya buruk sekarang)Jika Anda suka secara eksplisit, buat elemen bahasa Anda sendiri:
Bukankah ini sebenarnya cukup bagus?
Dan karena
sh
pada dasarnya hanya pekerjaan dan daftar string (dan proses internal, dari mana pekerjaan terdiri), kita sekarang bahkan dapat melakukan beberapa pemrograman fungsional ringan:Ini elegan. Bukannya saya menganjurkan penggunaan
sh
untuk sesuatu yang serius - itu rusak terlalu cepat pada persyaratan dunia nyata (tidak ada lambda, jadi kita harus menggunakan string. Tapi panggilan fungsi bersarang dengan string tidak mungkin, pipa tidak mungkin, dll.)sumber
case $HOST in user01 | node* ) ...
if case $HOST in node*) true;; *) false;; esac; then
Saya sudah melihatnya di sana-sini, bagi mata saya itu terlihat agak mengerut.case
perintah adalah perintah, mereka bisa masuk ke dalamif ... then
.beginswith() { case "$2" in "$1"*) true;; *) false;; esac; }
sebaliknya jika$1
memiliki literal*
atau?
mungkin memberikan jawaban yang salah.Anda dapat memilih hanya bagian dari string yang ingin Anda periksa:
Untuk pertanyaan tindak lanjut Anda, Anda bisa menggunakan OR :
sumber
${HOST:0:4}
HOST='a b'; if [ ${HOST:0:4} = user ] ; then echo YES ; fi
Saya lebih suka metode lain yang sudah diposting, tetapi beberapa orang suka menggunakan:
Edit:
Saya telah menambahkan alternatif Anda ke pernyataan kasus di atas
Dalam versi yang diedit, Anda memiliki terlalu banyak tanda kurung. Seharusnya terlihat seperti ini:
sumber
Sementara saya menemukan sebagian besar jawaban di sini cukup benar, banyak dari mereka mengandung Bashisme yang tidak perlu. Ekspansi parameter POSIX memberi Anda semua yang Anda butuhkan:
dan
${var#expr}
menghapus pencocokan awalan terkecilexpr
dari${var}
dan mengembalikannya. Oleh karena itu jika${host}
tidak tidak memulai denganuser
(node
),${host#user}
(${host#node}
) adalah sama dengan${host}
.expr
memungkinkanfnmatch()
wildcard, dengan demikian${host#node??}
dan teman juga bekerja.sumber
[[ $host == user* ]]
mungkin diperlukan, karena jauh lebih mudah dibaca daripada[ "${host#user}" != "${host}" ]
. Dengan demikian Anda dapat mengontrol lingkungan tempat skrip dijalankan (menargetkan versi terbarubash
), yang pertama lebih disukai.has_prefix()
fungsi dan tidak pernah melihatnya lagi.Sejak
#
memiliki makna dalam Bash, saya mendapatkan solusi berikut.Selain itu saya lebih suka mengemas string dengan "" untuk mengatasi spasi, dll.
sumber
blah:
, sepertinya ini adalah jawabannya!Menambahkan sedikit detail sintaksis ke jawaban peringkat tertinggi Mark Rushakoff.
Ekspresi
Bisa juga ditulis sebagai
Efeknya sama. Pastikan wildcard berada di luar teks yang dikutip. Jika wildcard ada di dalam tanda kutip, itu akan ditafsirkan secara harfiah (yaitu bukan sebagai wildcard).
sumber
@OP, untuk kedua pertanyaan Anda, Anda dapat menggunakan case / esac:
Pertanyaan kedua
Atau Bash 4.0
sumber
;&
hanya tersedia di Bash> = 4.tidak bekerja, karena semua
[
,[[
dantest
mengakui tata bahasa nonrecursive yang sama. Lihat bagian EKSPRESI KONDISI pada halaman Bash man Anda.Sebagai tambahan, kata SUSv3
Anda harus menulis seperti ini, tetapi tes tidak mendukungnya:
pengujian menggunakan = untuk kesetaraan string, dan yang lebih penting itu tidak mendukung pencocokan pola.
case
/esac
Memiliki dukungan yang baik untuk pencocokan pola:Ini memiliki manfaat tambahan yang tidak bergantung pada Bash, dan sintaksnya portabel. Dari Spesifikasi Unix Tunggal , Bahasa Perintah Shell :
sumber
[
dantest
Bash builtins serta program eksternal. Cobatype -a [
.if [ -z $aa -or -z $bb ]
; ... memberikan " bash: [: -atau: diharapkan operator biner "; Namunif [ -z "$aa" -o -z "$bb" ] ; ...
berlalu.grep
Lupa kinerja, ini POSIX dan terlihat lebih bagus daripada
case
solusi:Penjelasan:
printf '%s'
untuk mencegahprintf
memperluas backslash lolos: Bash printf string kata demi kata literalgrep -q
mencegah gema kecocokan ke stdout: Cara memeriksa apakah file berisi string tertentu menggunakan Bashgrep -E
memungkinkan ekspresi reguler yang diperluas, yang kami butuhkan untuk^
sumber
Saya mengubah jawaban @ markrushakoff untuk menjadikannya fungsi yang bisa dipanggil:
Gunakan seperti ini:
Ini adalah versi yang lebih kompleks yang menyediakan nilai default yang ditentukan:
Gunakan seperti ini:
sumber
Hal lain yang dapat Anda lakukan adalah
cat
mengetahui apa yang Anda gema dan lakukaninline cut -c 1-1
sumber