歡迎您光臨本站 註冊首頁

Ksh93 高級特性簡介

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
ksh 是 UNIX/Linux 下流行的 shell 語言,ksh93 是 ksh 的增強型版本;相比於 ksh,ksh93 提供了更接近於高級語言的特性,包括 c 風格的 for 循環,關聯數組,名字引用,複合變數和更方便的字元串操作,本文討論了這些高級特性並說明它們的應用。

ksh 是各種 UNIX 下的主要 shell 編程語言,許許多多的 UNIX 開發人員每天都在使用 ksh 做為它們日常的工作工具,當前比較流行的 ksh 版本主要有兩個,ksh88 和 ksh93 ;相對於 ksh88,ksh93 提供的特性讓 shell 編程人員的效率更加高效,下面我們逐一討論這些特性。

c 風格的 for 循環

傳統的 shell for 循環使用 for i in set 形式:

for i in 1 2 3 4 5    do    echo $i    done

ksh93 提供了對 c 風格 for 循環的支持,如下所示:

for((i=0; i<5; i++))    do       echo $i    done       對於在“ (( ”,“ )) ”中出現的 shell 變數,不需要在這些變數前加 $ 符號,比如

這項功能的加入也許是為了適應 c 編程人員眾多這個事實,所以受到 c 程序員的廣泛歡迎。

count=5    for((i=0; i<count; i++))    do    echo $i    done





關聯數組

普通數組使用整數做為下標,關聯數組則是使用字元串作為下標。使用關聯數組可以很容易的將兩方相互聯繫起來,這兩方在關聯數組中表示為數組字元串下標和數組值。

要使用關聯數組,首先要聲明它,下行語句聲明 dict 為關聯數組。

typeset -A dict

有兩種方法可以給 dict 赴初值;這是第一種,

dict[tree]="a lot of leaves"    dict[apple]="eclipse fruites"

這是第二種,

dict=(    [tree]="a lot of leaves"    [apple]="eclipse fruit"    )

要遍歷 dict,使用如下代碼

for i in ${!dict[*]};       # ${!dict[*]} 返回關聯數組 dict 的所有下標   do    echo ${dict[$i]};       # $i 是 dict 下標; ${dict[$i]} 取出 dict 的每個元素的值   done





名字引用

名字引用使函數參數傳遞,引用和修改更加簡單。在沒有引入名字引用之前,為了能在函數內部訪問實參,一種可選的方法是使用 eval 來實現間接變數引用,ksh93 使用名字引用使得這類代碼實現更加直觀和易讀。下例在函數 foo 中用“ typeset -n larray=$1 ”定義了局部變數 larray,它是 foo 的的第一個參數的名字引用;也可以使用“ nameref larray=$1 ”得到相同的效果。

array=(1 2 3)    function foo    {typeset -n larray=$1   # larray是形參;typeset i      for i in ${larray[*]}    do       echo $i    done    # 對形參 larray 做賦值操作,也就改變了實參   larray[0]=3; larray[1]=2; larray[2]=1;      }

運行 foo,將數組 array 作為參數

> foo array                                # array 是實參   1    2    3    > echo ${array[*]}                           # array 確實被 foo 改變了   3 2 1





複合變數

複合變數提供了類似於高級語言中結構的功能。

以下 ksh 語句使用複合變數定義了 desk 變數,它有三個域 name,id 和 price 。

desk=(    typeset name=yijia    integer id=1    float   price=340.5    )

使用 ${desk.name} 來引用 desk 的 name 域

> echo ${desk.name}    yijia

將複合變數和間接變數引用相結合就能用 ksh93 實現教科書上線性鏈表等標準數據結構。

以下例子給出長度為 2 的一個線性鏈表,讀者可以用類似方法模仿樹的實現。

注意,我們稱 next 為指針,僅是借用了 c 語言指針的說法,它和 c 中的指針在實現上是不一樣的,但是概念類似,即都是屬於間接訪問這個類型。

#!/bin/ksh    # /tmp/link.sh      second=(                                    # 複合變數 second,next 指針為空   data=1    next=null    )    first=(                                      # 複合變數 first,next 指針為 second    data=2    next=second    )    p=first                                      # 將指針 p 初始化為 first    while [[ $p != "null" ]]                     # 如果指針 p 為空,退出循環   do       eval data=\${${p}.data}; echo "data=${data}";        # 取出和列印元素 data       eval p=\${${p}.next};    echo "p=$p";                # 將 p 指向下一個元素   done      > /tmp/link.sh                                           # 執行 link.sh    data=2    p=second    data=1    p=null





更方便的字元串操作

程序員日常工作中是經常遇到的操作之一就是字元串操作,ksh93 自然不會放過這方面的增強。

表 1 總結了 ksh93 在字元串處理方面的加強,假設 string 等於 abc123abc 。


表 1. 更強的字元串處理
功能 語法 樣例
求起始位置為 index 的子串 ${param:offset} > echo ${string:3}
123abc
求起始位置為 index 和長度 num 的子串 ${param:offset:num} > echo ${string:1:3}
bc1
替換第一個出現的 pattern為 repl ${parm/pattern/repl} > echo ${string/abc/def}
def123abc
替換所有出現的 pattern 為 repl ${parm//pattern/repl} > echo ${string//abc/def}
def123def
替換開頭的 pattern ${parm/#pattern/repl} > echo ${string/#abc/def}
def123abc
替換結尾的 pattern ${parm/%pattern/repl} > echo ${string/%abc/def}
abc123def


[火星人 ] Ksh93 高級特性簡介已經有909次圍觀

http://coctec.com/docs/linux/show-post-68817.html