Linux Bash Shell學習(八):shell編程基礎——string操作

來源:互聯網
上載者:User

  本文也即《Learning the bash Shell》3rd Edition的第四章Basic Shell Programming之讀書筆記之二,但我們將不限於此。

String操作

  在下面的描述中,“:”是可以刪除的,存在是表示“存在但不允許為null”,不帶“:”表示“存在”,即允許為空白:

${

varname

:-

word

}

:如果varname存在並且不為null,返回varname的值,否則返回word。用於當某個變數不存在或沒定義時返回一個預設的值。如果為${

varname

-

word

}

,則當varname存在,可以為null,例如我們定義myparam=,返回varname的值,否則返回word。下面也可以刪除“:”,含義相同,不在複述。

${

varname

:=

word

}

:如果varname存在並且不為null,返回varname的值,否則向其賦值為word,並返回該值。用於對某個不存在或沒定義變數設定預設。對於位置參數是唯讀不能賦值。

${

varname

message

}

:如果varname存在並且不為null,返回varname的值,否則列印資訊varname:message,並abort指令碼,如果我們沒有設定message,將使用預設的“parameter null or not set”。用於檢查變數沒有定義的錯誤。

${

varname

:+

word

}

:如果varname存在並且不為null,返回word的值,否則返回null。用於檢測變數是否存在。

${

varname

:

offset

:

length

}

:擷取substring的操作。他返回從varname中從offset位置開始,長度為length的字串。第一個位置為0,如果不給出length或者無效(小於0),則返回offset之後全部的字元,如果是{@:offset:length},則返回指令碼參數從第offset個參數開始的總共length個參數。

  下面給出一個例子來學習他們的用法。我們建立一個檔案,在裡面存貯一些條目,我們希望能對條目進行排序,從大到小,並輸出最前的N個條目。檔案例如子如下:

[wei@wei-desktop bash-learning]$ cat myinfo

5    Depeche Mode

2    Split Enz

3    Simple Minds

1    Vivaldi, Antonio

20  Hello, world

7    adsf,dafdsf

15  Hello, myfriend

  我們建立我們的指令檔highest用作測試,內容如下:其他顏色字型表示說明,不作為檔案的一部分,我們用注釋的方式,也不影響檔案的執行

# ”#“開始表示注釋行,一個良好的變成習慣是檔案的開始給出檔案的資訊,以便閱讀

# highest [howmany]

# sort the entry inf on a descend order, and high line the top

# [hwomany] entry, default is 5

#
# 要求使用者給出參數<檔案名稱>,否則退出指令碼,要求使用者給出顯示的條目,否則使用預設值5

filename=${1? 'Used command ./test [entry_num]'}

howmany=${2:-5}

# header是用來表明輸出的時候顯示的某些資訊,如果這行我們注釋掉,將不顯示

header=set
#echo帶有兩個參數-n,表示顯示後不執行LINEFEED,即不換行。-e表示解析/n,不將其作為兩個字元,視為分行符號號。我們如果注釋掉header,則不會顯示任何內容。

echo -e -n ${header:+"num    name/n"}

echo -e -n ${header:+"----    -----/n"}
#sort是個排序的命令,-r表示reverse的順序,即從大到小,-n表示將第一個參數視為數字,而不是character的方式。| 表示pipe輸出,head -N

表示顯示頭N行。

sort -nr $filename | head -$howmany

樣式匹配

  Pattern可以包含wildcard,操作如下:

  • ${variable

    #pattern

    }

    :如果變數的開始匹配pattern,則去除最小匹配,返回後面的字元,如果不匹配,給出變數。

  • ${variable

    ##pattern

    }

    :如果變數的開始匹配pattern,則去除最大匹配,返回後面的字元,如果不匹配,給出變數。

  • ${variable

    %pattern

    }

    :如果變數的最後匹配pattern,則去除最小

    匹配,返回前面的字元,如果不匹配,給出變數。

  • ${variable

    %%pattern

    }

    :如果變數的最後匹配pattern,則去除最大匹配,返回前

    面的字元,如果不匹配,給出變數。

  • ${variable

    /pattern/string

    }

    :將第一個匹配更換為string,如果string為null,則刪除。如果variable是@或者*,則根據命令所得的參數為單元來執行。

  • ${variable

    //pattern/string

    }

    :將所有匹配更換為string,如果string為null,則刪除。如果variable是@或者*,則根據命令所得的參數為單元來執行。

  最大或者最小批評只有在含有萬用字元的情況下有區別,否是對於精確匹配都是無區別的。下面是例子。

[wei@wei-desktop bash-learning]$ echo $aa

abc.xyz.hello.world

[wei@wei-desktop bash-learning]$ echo ${aa#*.}

xyz.hello.world

[wei@wei-desktop bash-learning]$ echo ${aa##*.}

world

[wei@wei-desktop bash-learning]$ echo ${aa%.*}

abc.xyz.hello

[wei@wei-desktop bash-learning]$ echo ${aa%%.*}

abc

[wei@wei-desktop bash-learning]$ echo ${aa/./-}

abc-xyz.hello.world

[wei@wei-desktop bash-learning]$ echo ${aa//./-}

abc-xyz-hello-world

  圖案匹配經常用於檔案名稱的處理,例如去除路徑名,擷取檔案尾碼或者首碼等等。

  查看extglob的選項是否開啟:shopt | grep extglob,如果開啟,可以使用或擴充的樣式匹配。開啟檔案shopt -s exglob,關閉使用-u。可以用這些來替代萬用字元:

  • *(patternlist

    )

    ,其中paternlist的格式為pattern1|pattern2|pattern3|….,表示匹配0個或者多個pattern

  • +(patternlist

    )

    ,表示匹配1個或者多個pattern

  • ?(patternlist

    )

    ,表示匹配0個或者1個pattern

  • @(patternlist

    )

    ,表示匹配1個pattern

  • !(patternlist

    )

    ,表示不匹配任何的pattern

  例子,echo ${aa//+(abc|hello)/ALICE}的值為ALICE.xyz.ALICE.world

長度操作

  ${#varname

}

,例如上面的例子中${#aa}為19。

command substutuion:使用命令的輸入作為賦值

  可以通過command substitution

來設定參數的值。允許將命令的輸出作為變數的賦值。在makefile的編寫中,我們曾使用類似的方式即`pkg-config clutter-1.0 --libs`,這裡用``包含的內容就是命令執行的輸出結果。但是這種方式是為了和舊版本相容,可以使用$(UNIX command

)的方式。這種方式可以嵌套的,及裡面的UNIX command也可以是command substitution。但是使用``的方式無法實現嵌套,下面是一些例子:

  • $(ls $(pwd)),給出目前的目錄的檔案。例如$(ls $HOME),給出使用者目錄~下面的檔案。
  • 例如type -all -path command給出命令的路徑,如果我們需要仔細查看相關檔案屬性,可以使用ls -l $(type -all -path vi)。
  • vi $(grep -l 'command substitution' ch*),表示編輯目前的目錄開ch大頭的含有'command substitution'內容的檔案,其中-來表示,只顯示目標檔案。


cut和awk的用法:擷取列資訊

  這兩個適用於獲得列的方式,舊的BSD系統不提供cut,需要使用awk來替代。使用方式cut –fN –dC filename或者awk –FC '{print $N}' filename。其中N表示列出,C表示分割符號,預設為tab。如果我們使用空格,可以為’ ‘,如果使用|等或產生奇異的特殊符合用/|的方式。例如顯示使用者名稱cat /etc/passwd | cut –f1 –d:。對於命令在stdout的輸出,使用空格對其,例如who,我們可以使用參數-cX-Y的方式,表示顯示為開始的第X個字元到第Y個字元,X從1開始,如果沒有Y,表示一直顯示到最後。例如who | cut –c10-15

一個stack的小例子

  下面我們給出一個FILO的stack例子,用來複習string的操作。

push_func()

{

   #注意如果沒有給出func的參數,則在func中跳出,而不是終結整個指令碼

    entry=${1:?"Please enter the entry as push_func param"}

    #注意在bottow後面有一個空格,我們使用空格作為分割,這是為了pop最後一個entry用

    mystack="$entry ${mystack:-bottow }"

    echo "push $entry in stack : $mystack"

}

pop_func()

{

    #刪除最top的entry

    mystack=${mystack#*' '}

   #擷取當前stack的top元素


    entry=${mystack%% *}

    echo "After pop, top entry is '$entry', stack is $mystack"

}

push_func one

push_func

push_func two

pop

pop

pop

相關連結:
我的Linux操作相關文章

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.