Sadece yap:
case $1 in
(*:*) host=${1%:*} port=${1##*:};;
(*) host=$1 port=$default_port;;
esac
Sen değiştirmek isteyebilirsiniz case $1için case ${1##*[]]}değerleri için hesaba $1gibi [::1](olmadan IPv6 adresi liman kısmında).
Bölmek için split + glob operatörünü kullanabilirsiniz (bir parametre genişletmesini derecelendirilmemiş olarak bırakın).
set -o noglob # disable glob part
IFS=: # split on colon
set -- $1 # split+glob
host=$1 port=${2:-$default_port}
(ancak bu, iki nokta üst üste içeren ana makine adlarına izin vermez (yukarıdaki IPv6 adresi için olduğu gibi)).
Bu split + glob operatörü yoluna girer ve o kadar çok zarara neden olur ki , gerektiğinde sadece adil görünecektir (yine de, özellikle POSIX'in shhiç olmadığı düşünülerek kullanmanın çok hantal olduğunu kabul edeceğim. değişkenler için (de, yerel kapsam destek $IFSburaya) ne amaç için ( noglobburada) (olsa ashtürevleri gibi ve dashbirlikte AT & T uygulamaları ile (do olanlardan bazıları ksh, zshve bashyukarıda 4,4 ve)).
Bunun IFS=: read A B <<< "$1"birkaç sorunu olduğunu unutmayın :
- Unuttuğun
-rbazı özel işleme tabi olacak ters eğik çizgi hangi araçları.
- o bölmek
[::1]:443içine [ve :1]:443yerine [(ve boş dize kendisi için ihtiyacım olacağını IFS=: read -r A B rest_ignoredya [::1]ve 443) (bunlar için bu yaklaşımı kullanamazsınız
- Kullanmak sürece (keyfi dizeleri ile kullanılamaz nedenle, yeni satır karakteriyle ilk geçtiği geçmiş herşeyi şeritler
-d ''halinde zshveya bashve veriler herestrings (veya heredoc boş karakter ama sonra dikkat etmeyen bir eklerim) ekstra yeni satır karakteri!)
- içinde
zsh(sözdizimi nereden geldiğini) ve bashgenellikle kullanmaktan daha az verimli yüzden, burada dizeleri, geçici dosyaları kullanılarak uygulanan ${x#y}veya bölünmüş + glob operatörler.