Linux Bash Shell學習(八):shell程式設計基礎——string操作
本文也即《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'內容的檔案,其中-來表示,只顯示目標檔案。這兩個適用於獲得列的方式,舊的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操作相關文章
相關文章
- Linux Bash Shell學習(七):shell程式設計基礎——執行Shell指令碼、functionLinux程式設計指令碼Function
- Linux_day06_01_Shell指令碼程式設計_Bash基礎Linux指令碼程式設計
- Linux學習(Shell基礎)Linux
- Shell程式設計-基礎程式設計
- shell程式設計基礎程式設計
- Bash Shell 基礎特性
- 如何學習shell程式設計?Linux運維學習shell程式設計是什麼程式設計Linux運維
- Linux學習-shell基礎02Linux
- 玩轉Linux – shell 程式設計基礎Linux程式設計
- 前端學習 linux —— shell 程式設計前端Linux程式設計
- Shell程式設計基礎學習之六:sed 入門程式設計
- shell程式設計基礎二程式設計
- shell程式設計–bash變數程式設計變數
- 9.bash shell程式設計程式設計
- Linux Shell指令碼程式設計-基礎1Linux指令碼程式設計
- Linux系統程式設計(12)——shell基礎Linux程式設計
- Linux-shell程式設計入門基礎Linux程式設計
- 【學習】Linux Shell指令碼程式設計Linux指令碼程式設計
- Linux Shell 程式設計學習筆記Linux程式設計筆記
- Shell程式設計基礎學習之四:語法結構程式設計
- Shell程式設計基礎學習之三:變數和test程式設計變數
- Shell程式設計基礎學習之一:正規表示式程式設計
- shell指令碼程式設計基礎指令碼程式設計
- BASH SHELL 程式設計簡介(轉)程式設計
- Shell(Bash)學習· 總章
- Linux之19——Shell程式設計基礎詳解Linux程式設計
- Linux Shell程式設計(15)——操作字串Linux程式設計字串
- Linux程式設計-11.Shell Script(bash)--(2)教學例(轉)Linux程式設計
- Linux Bash Shell學習(十):流程控制——forLinux
- 學習Shell程式設計要掌握哪些基礎?linux運維工程師前景程式設計Linux運維工程師
- Shell 學習筆記 基礎筆記
- shell程式設計–bash變數介紹程式設計變數
- BASH Shell的指令碼程式設計(轉)指令碼程式設計
- Shell程式設計基礎學習之二:變數的基本認知程式設計變數
- Linux Shell程式設計(27)——子shellLinux程式設計
- Linux Shell程式設計(1)——shell程式設計簡介Linux程式設計
- Linux Shell程式設計(12)——操作符Linux程式設計
- Linux Bash Shell學習(九):流程控制——if/elseLinux