Sintaks bash berikut memverifikasi jika param
tidak kosong:
[[ ! -z $param ]]
Sebagai contoh:
param=""
[[ ! -z $param ]] && echo "I am not zero"
Tidak ada output dan baik-baik saja.
Tetapi ketika param
kosong kecuali untuk satu (atau lebih) karakter spasi, maka kasusnya berbeda:
param=" " # one space
[[ ! -z $param ]] && echo "I am not zero"
"Saya bukan nol" adalah output.
Bagaimana saya bisa mengubah tes untuk mempertimbangkan variabel yang hanya berisi karakter spasi sebagai kosong?
bash
shell
shell-script
string
maihabunash
sumber
sumber
man test
:-z STRING - the length of STRING is zero
. Jika Anda ingin menghapus semua spasi$param
, gunakan${param// /}
trim()
fungsi sederhana bawaan untuk * nix sama sekali? Begitu banyak peretasan yang berbeda untuk mencapai sesuatu yang sangat sederhana ...[[ ! -z $param ]]
itu setara dengantest ! -z $param
.Jawaban:
Pertama, perhatikan bahwa
-z
tes ini secara eksplisit untuk:Artinya, string yang hanya berisi spasi tidak boleh benar di bawah
-z
, karena memiliki panjang non-nol.Yang Anda inginkan adalah menghapus spasi dari variabel menggunakan ekspansi parameter penggantian pola :
Ini memperluas
param
variabel dan mengganti semua kecocokan pola(satu spasi) dengan apa-apa, sehingga string yang hanya memiliki spasi di dalamnya akan diperluas ke string kosong.
The seluk-beluk bagaimana yang bekerja adalah bahwa
${var/pattern/string}
menggantikan pertandingan terpanjang pertamapattern
denganstring
. Ketikapattern
dimulai dengan/
(seperti di atas) maka itu akan menggantikan semua kecocokan. Karena penggantinya kosong, kami dapat menghilangkan final/
danstring
nilainya:Setelah semua itu, kami akhirnya
${param// }
menghapus semua spasi.Perhatikan bahwa meskipun ada di
ksh
(tempat asalnya),zsh
danbash
, sintaks itu bukan POSIX dan tidak boleh digunakan dalamsh
skrip.sumber
sed
kata mereka ... hanyaecho
variabel yang mereka katakan ...${var/pattern/string}
bukankah seharusnya[[ -z ${param/ /} ]]
dengan ruang antara garis miring menjadi polanya dan tidak ada apa-apanya menjadi tali?[[ -z "${param// }" ]]
pasti terlihat sepertipattern
kosong danreplacement string
satu spasi. AH! Saya melihatnya sekarangif pattern begins with a slash
saya melewatkan bagian itu. begitu polanya/
dan senarnya ditinggalkan dan oleh karena itu kosong. Terima kasih.Cara mudah untuk memeriksa bahwa string hanya berisi karakter dalam set yang diotorisasi adalah untuk menguji keberadaan karakter yang tidak sah. Jadi, alih-alih menguji apakah string hanya berisi spasi, uji apakah string berisi beberapa karakter selain spasi. Dalam bash, ksh atau zsh:
“Terdiri dari spasi saja” termasuk case dari variabel kosong (atau tidak disetel).
Anda mungkin ingin menguji karakter spasi apa saja. Gunakan
[[ $param = *[^[:space:]]* ]]
untuk menggunakan pengaturan lokal, atau daftar karakter spasi kosong apa pun yang ingin Anda uji, misalnya[[ $param = *[$' \t\n']* ]]
untuk menguji ruang, tab, atau baris baru.Mencocokkan string dengan pola
=
di dalam[[ … ]]
adalah ekstensi ksh (juga ada dalam bash dan zsh). Dalam gaya Bourne / POSIX apa pun, Anda bisa menggunakancase
konstruk untuk mencocokkan string dengan suatu pola. Perhatikan bahwa pola shell standar digunakan!
untuk meniadakan set karakter, daripada^
seperti dalam kebanyakan sintaks ekspresi reguler.Untuk menguji karakter spasi,
$'…'
sintaks khusus untuk ksh / bash / zsh; Anda dapat memasukkan karakter-karakter ini dalam skrip Anda secara harfiah (perhatikan bahwa baris baru harus berada dalam tanda kutip, karena garis miring terbalik + baris baru tidak meluas), atau menghasilkannya, misalnyasumber
${var?not set}
- melewati tes itu dan bertahan akan memastikan bahwa variabel yang cocok dengan Anda*)
case
akan mempengaruhi definitif jawab, misalnya.[[ $param = *[!\ ]* ]]
dimksh
.POSIXly:
Untuk membedakan antara kosong , tidak kosong , kosong , tidak disetel :
[:blank:]
adalah untuk karakter spasi horizontal (spasi dan tab di ASCII, tetapi mungkin ada beberapa lagi di lokal Anda; beberapa sistem akan menyertakan ruang tanpa-putus (jika tersedia), beberapa tidak akan). Jika Anda juga ingin karakter spasi vertikal (seperti baris baru atau umpan formulir), ganti[:blank:]
dengan[:space:]
.sumber
zsh
tampaknya memiliki masalah dengan[![:blank:]]
, itu meningkatkan:b
pengubah tidak valid. Dalamsh
danksh
meniru, itu meningkatkan acara yang tidak ditemukan untuk[
var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'
tidak apa-apa untuk saya. Acara tidak ditemukan hanya untuk shell interaktif.:b
pengubah valid agak aneh.sh
adalahbash
dibangun dengan--enable-xpg-echo-default
dan--enable-strict-posix-default
sehingga menjadi Unix compliant (yang melibatkanecho '\t'
keluaran tab).Satu-satunya alasan yang tersisa untuk menulis skrip shell, alih-alih skrip dalam bahasa skrip yang baik , adalah jika portabilitas ekstrem menjadi perhatian utama. Warisan
/bin/sh
adalah satu-satunya hal yang bisa Anda yakini miliki, tetapi Perl misalnya lebih mungkin tersedia lintas platform daripada Bash. Oleh karena itu, jangan pernah menulis skrip shell yang menggunakan fitur yang tidak benar-benar universal - dan perlu diingat bahwa beberapa vendor Unix miliknya membekukan lingkungan shell mereka sebelum POSIX.1-2001 .Ada cara portabel untuk melakukan tes ini, tetapi Anda harus menggunakan
tr
:(Nilai default
$IFS
, mudahnya, adalah spasi, tab, dan baris baru.)(
printf
Builtin itu sendiri portabel, tetapi mengandalkan itu jauh lebih mudah daripada mencari tahu varian yangecho
Anda miliki.)sumber
case
.case
glob untuk mendeteksi string yang kosong, atau hanya berisi karakter spasi putih. (Itu akan mudah dengan regexp, tetapicase
tidak melakukan regexps. Konstruk dalam jawaban Anda tidak akan berfungsi jika Anda peduli dengan baris baru.)case $param in *[![:space:]]*) …
. Jika Anda ingin mengujiIFS
karakter, Anda dapat menggunakan polanya*[$IFS]*
.<space><tab><newline>
di awal dan kemudian tidak pernah menyentuhnya lagi. Saya pikir itu akan menjadi gangguan..profile
yang telah dieksekusi oleh banyak peluru Bourne. Tentu saja[$IFS]
tidak akan melakukan apa yang dimaksudkan jikaIFS
memiliki nilai-nilai non-default tertentu (kosong (atau tidak disetel), berisi]
, dimulai dengan!
atau^
).sumber
Untuk menguji apakah variabel kosong atau mengandung spasi, Anda juga dapat menggunakan kode ini:
sumber
:
.name=aaaa
kemudian jalankan perintahecho ${name:?variable is empty}
ini akan mencetak nilai nama variabel dan sekarang jalankan perintah iniecho ${name1:?variable is empty}
ia akan mencetak -sh: name1: variabel kosongecho ${name:?variable is empty}
akan mengevaluasi$name
nilai bukan nol atau akan mematikan shell. Jadi untuk alasan yang sama Anda tidak melakukannyaprompt > $randomvar
juga tidak boleh${var?}
- jika ada perintah di sana, itu mungkin akan berjalan - dan Anda tidak tahu apa itu. Shell interaktif tidak harus keluar - itulah sebabnya Anda tidak perlu keluar. Namun, jika Anda ingin melihat beberapa tes, ada banyak tes di sini. . Yang ini tidak cukup lama ...Untuk menguji apakah suatu variabel tidak disetel, kosongkan (memiliki nilai nol) atau hanya berisi spasi:
Penjelasan:
${param%%[! ]*}
pemindahan dari non-ruang pertama ke akhir.-z
, maka gemaempty
.Di atas adalah POSIX yang kompatibel dan berjalan di keturunan Bourne.
Jika Anda ingin memperluas itu juga tab, sertakan tab eksplisit:
atau gunakan variabel dengan karakter yang perlu Anda hapus:
atau Anda dapat menggunakan beberapa "ekspresi kelas karakter" POSIX (kosong berarti spasi dan tab):
Tapi itu akan gagal di mksh, lksh dan posh.
sumber
Coba ini:
sumber