本文主要來源:
<<Shell 腳本學習指>>
http://blog.csdn.net/lile269/article/details/6387553
http://bbs.chinaunix.net/thread-691881-1-1.html
http://wenku.baidu.com/link?url=PefwLPTAQDnP1HLMpJgJhF04kFLbaBj9GFE9D5MYg0pHX8RsxeheHq_DJuZujDq7rK02GtVbtC-FIfllck8yeqm1GLl1LdkY5N2ILA1TO5i
http://blog.sina.com.cn/s/blog_5e77c61f0100hqky.html
http://blog.csdn.net/weekly123/article/details/1465675
http://blog.163.com/[email protected]/blog/static/16718749120118251544885/
1. Shell正規表達式
(1)meta字元
POSIX BRE與ERE的meta字元
\ : 關閉後續字元的特殊意義。\(...\)與\{.....\}
. : 比對任何單個的字元,但NULL除外;
* : 比對它之前的任何數目(或沒有)的單個字元
^ : 比對緊接着的正規表達式,在行或字元串的起始處。
$ : 比對前面的正規表達式,在字元串或行結尾處。
[...] : 比對方括号内的任一字元,連字元(-)指的是連續字元的範圍; ^符号置于方括号裡第一個字元則有反向含義,指的是比對不在清單内(方括号内)的任何字元。
BRE僅有的
\{n, m\}: 區間表達式(interval expression),比對在它前面的單個字元重制的次數區間。
\{n\}指的是重制n次;\{n,\}至少重制n次;\{n, m\}指重制n至m次;
\(\): 将\(與\)間的模式存儲在特殊的“保留白間(holding space)”。最多可将9個獨立的subpattern存儲在單個模
式中。可通過轉義序列\1到\9,被重複使用在相同模式裡。eg:\(ab\).*\1指的是比對于ab組合的兩次重
現,中間可存在任何數目的字元。
\n: 重複在\(與\)方括号内第n個子模式至此點的模式,n為1至9的數字,1為由左開始
ERE獨有的:
{n, m}: 與BRE中的\{n, m\}一樣
+ : 比對前面正規表達式的一個或多個執行個體
? : 比對前面正規表達式的零個或一個執行個體
|: 比對于|符号前或後的正規表達式
( ): 比對于方括号括起來的正規表達式群
[: :] : 字元集
[. .] :排序符号
[= =]: 等價字元集
(2)後向引用
(3)文本比對錨點
(4)BRE運算符優先級、由高至低
(5)ERE運算符優先級、由高至低
(6)正規表達式的擴充
2. Shell中重要的指令用法
(1)grep用法
文法: grep [ options ...] pattern-spec [ files...]
用途:列印出與pattern相比對的行
選項:
常用選項:
-c 隻輸出比對行的計數。
-i 不區分大小寫(隻适用于單字元)。
-h 查詢多檔案時不顯示檔案名。
-l 查詢多檔案時隻輸出包含比對字元的檔案名。
-n 顯示比對行及行号。
-s 不顯示不存在或無比對文本的錯誤資訊。
-v 顯示不包含比對文本的所有行。
(2)sed用法
工作方式: sed工具按順序逐行将檔案讀入到内在中,它執行為該行指定的所有操作,并在完成請求的修改之後将該行放回到内在中,以将其轉儲至終端,完成操作之後中,讀取檔案的下一行,重複該過程直到它完成該檔案。(輸出可被重定向到另一檔案中,以儲存變化;源檔案(預設地)保持不被修改。)
文法: sed [options] '{command}' [filename]
替換指令: 's/{old value}/new value/'
對某一行多次修改: 使用‘-e’選項:
或使用分号:注:分号必須是緊跟/之後的字元,不能出現空格
或使用延續符: >
全局修改: 當某一行中同時出現多個比對時,僅替換掉第一個,若要替換點全部,需指定全局操作 g
sed可用來修改記錄字段分隔符 例:将所有的tab修改為空格: sed 's// /g'
sed修改指定情況下的某些行
用腳本檔案來修改,使用 -f 參數:
修改指定的行:
-n 參數:
删除行: 參數:d
sed中的 a 指令: 将文本添加到檔案末尾
讀寫
修改指令:
退出操作: q 指令
&:表示從此點開始替代成比對于正規表達式的整個文本
執行個體: sed '2,5d' file 顯示檔案file,除去2-5行,但行數超過檔案實際行數時不會報錯。 sed '/10[1-4]/d' file 顯示檔案file,除去包含101-104的行。
sed '2,$d' file 顯示檔案,隻顯示第一行。 sed '2,$!d' file則隻顯示除第一行外的其它行。
sed '/^ *$/d file 删除檔案中的空行。
sed -n '/10[1-4]/p' file 隻顯示檔案file中包含101-104的行。(-n和p必須同時使用,否則隻有p時顯示全部檔案并多顯示一次找到的行)
sed -n '5p' file 隻顯示檔案的第5行
sed 's/moding/moden/g' file 将moding替換為moden
sed -n 's/^west/north/p' file 将west開頭的行替換為north并顯示出來。
sed 's/[0-9][0-9][0-9]$/&.5/' file将file檔案中以3個數字結尾的行替換為原數字加".5",&代表搜尋到的字元串。
sed 's/\(mod\)ing/\1en/g file 将mod做為模式1封裝在括号裡,然後替換。
sed 's/...$//' file 删除每一行的最後三個字元。
sed 's/^...//' file 删除每一行的頭三個字元。
sed 's#moding#moden#g' file 将moding替換為moden,s後面的#代表搜尋串和替換串之間的分界符。
sed -n '/101/,/105/p' file 顯示從101的比對行到105的比對行。如果隻找到101的比對行,則從101的比對行到檔案末。
sed -n '2,/999/p' file 顯示從第2行到比對行。
sed '/101/,/105/s/$/ 20050119/' file将從101的比對行到105的比對行的行末增加" 20050119"内容。
sed -e '1,3d' -e 's/moding/moden/g' file 先删除檔案的1-3行,再進行替換。
sed -e '/^#/!d' file 顯示檔案以#開頭的行。
sed '/101/r newfile' file 在每個比對行增加檔案newfile的内容
sed '/101/w newfile' file 把比對行寫入newfile。
sed '/101/a\
> ###' file 在比對行後增加一新行。
sed '/101/i\
> ###' file 在比對行前增加一新行。
sed '/101/c\
> ###' file 用新行替換比對行。
sed 'y/abcd/ABCD/' file 将a、b、c、d分别替換為ABCD。
sed '5q' file 顯示到第5行時退出。
sed '/101/{ n; s/moding/moden/g; }' file 在檔案中找到比對行的後一行(n)再進行替換。
sed '/101/{ s/moding/moden/g; q; }' file 在檔案中找到第一個比對行後進行替換後再退出。
sed -e '/101/{ h; d; }' -e '/104/{ G; }' file 在檔案中找到與101比對行後先存在一個緩存中,再放在與104比對行後。
sed -e '/101/{ h; d; }' -e '/104/{ g; }' file 在檔案中找到與101比對行後先存在一個緩存中,再替代104的比對行。
sed -e '/101/h' -e '$G' file 将最後一個比對行放在檔案末。
sed -e '/101/h' -e '$g' file 将最後一個比對行替換檔案末行。
sed -e '/101/h' -e '/104/x' file 在檔案中找到與101比對行後先存在一個緩存中,再與104的比對行進行互換。
sed -f sfile file 根據檔案sfile的指令清單進行操作。
cat sfile
/101/a\
####101####\
****101****
/104/c\
####104 deleted####\
****104 deleted****
1i\
####test####\
****test****
(3)cut指令
cut用于從檔案或标準輸入中讀取内容并截取每一行的特定沖毀并送到标準輸出。
cut指令主要接受三個定位方法: 位元組(bytes),選項為 -b 字元(characters),選項為-c 域(fields),選項為-f
位元組定位:
字元定位: (在cygwin下,結果有點問題哦)
-c以字元赤機關 -b以位元組為機關
-n選項,告訴cut不要将多位元組拆開
“域”操作:對于非固定格式的資訊,“域”可派上用場。設定“間隔符”,再設定“提取第幾個域”。
在設定-f時,也可以使用例如3-5或者4-類似的格式
(4)join指令
join指令用來連接配接兩個檔案中的相同鍵值的其餘内容後輸出。 文法: join [options....] file1 file2 選項: -1 field1,-2 field2:選擇file1中的field1字段和file2中的field2字段作為鍵值。 -o file.field:輸出file中的field字段。通常file是1或2。 -t seperator:使用seperator作為輸入字段的分隔符而非使用空格或TAB. 若想指定file1為标準輸入,請使用-
(5)awk指令
可參考資源: http://game-lab.org/wiki/index.php/AWK%E2%80%94%E6%96%87%E6%9C%AC%E6%B5%81%E7%BC%96%E8%BE%91%E5%99%A8
-F 參數的使用:
(6)sort指令
一般格式: sort -cmu -o output_file [other options] +pos1 +pos2 input_files
-c 測試檔案是否已經分類。
-m 合并兩個分類檔案。
-u 删除所有複制行。
-o 存儲s o r t結果的輸出檔案名。
其他選項有:
-b 使用域進行分類時,忽略第一個空格。
-n 指定分類是域上的數字分類。
-t 域分隔符;用非空格或t a b鍵分隔域。
-r 對分類次序或比較求逆。
+n n為域号。使用此域号開始分類。
n n為域号。在分類比較時忽略此域,一般與+n一起使用。
post1 傳遞到m,n。m為域号,n為開始分類字元數;例如4,6意即以第5域分類,從第7個字元開始。
-t選項的使用:
預設情況下,sort認為“一個空格”或“一系列空格”,要加入其他方式分隔,使用-t(-t+分隔符)選項 第一列作為第一個域為域0,域1是第二個域等等。
-c參數的使用:
-r參數:逆向sort結果:
-u參數:唯一性分類
-k參數: 進一步控制排序操作,可使用-k選項指定排序字段,并使用-t選項來選擇字段定界符 未指定-t,則表示字段以空白分隔且記錄内開頭與結尾的空白都将忽略; 指定-t,則被指定的字元會分隔字段,且空白是有意義的。
-k3nr, 3(表示從字段3起始處開始,以數值類型反向排序,并結束于字元3的結尾)或 -k3, 3nr 甚至是-k3,3,-n,-r
文本塊排序
(7)uniq指令
uniq有3個選項: 不帶參數重複的行僅出現一次 -c在每個輸出行前加上該行重複的次數 -d僅顯示重複的行 -u僅顯示未重複的行
(8)fmt指令
重新格式化文本段落,供使用者切分段落 fmt的選項 -s:僅切割較長的行,但不會将短行結合成較長的行 -w n: 則設定輸出行寬度為n個字元(預設通常為75個左右)【所有版本都禁止将寬度設定為0,但接受-w 1或-1的用法 】
(9)計算行數、字數及字元數
wc指令:-c(位元組數)、 -l(行數)及-w(字數) wf指令:統計每個單詞發生頻率的相關工具
(10)pr指令
過濾資料為列印作準備
(11)提取開頭或結尾數行
3. Shell中的文法
Shell腳本 與函數有位置函數(positional parameter)的功能,即“指令行參數”
(1)變量管理:export與readonly、env
文法: export name[=word] ...
export -p
readonly name[=word] ...
readonly -p
用途: export用于修改或列印環境變量【将變量放進環境裡或對共進行修改】,readonly則使得變量不得修改
選項: 使用-p選項,列印出名稱及被導出的或隻讀的所有變量與值; 否則,會将适當的屬性應用到指定的變量。
env指令: 可從程式的環境中删除變量,也可改變環境變量值 文法: env [-i] [ var = value...] [command_name [ arguments ... ]] 選項: -i 忽略繼承的環境,僅使用指令行上所給定的變量與值
unset指令: 可從執行中的Shell中删除變量與函數 文法: unset [ -v ] variable ... unset -f funciton 選項: -f解除(删除)指定的函數 -v 解除(删除)指定的變量,沒有任何選項時,預設的行為是模式【即參數将視為變量名稱,并告知變量已删除】
(2)參數展開
參數展開(parameter expansion)是提供變量值在程式中使用的過程
展開運算符
運算符 | 替換 |
---|---|
${varname: - word} | 若varname存在且非null,則傳回其值;否則,傳回word; 用途:如果變量未定義,則傳回預設值 eg:若count未定義,則${count: -0}的值為0 |
${varname:=word} | 若varname存在且不是null,則傳回它的值;否則,設定它為word 并傳回其值; 用途:若變量未定義,則設定變量為預設值 eg:若count未定義,則${count:=0}設定為0 |
${varname:?message} | 若varname存在且非null,則傳回它的值;否則, 顯示varname:mesage,并退出目前的指令或腳本 用途:捕捉由于變量未定義所導緻的錯誤 eg:${count:?"undefined!"}将顯示count:undefined! 且若count未定義,則退出 |
${varname:+word} | 若varname存在且非null,則傳回word;否則,傳回null; 用途:為測試變量的存在 eg:若count已定義,則${count:+1}傳回1 |
每個運算符内的冒号(:)都是可逆的,若省略冒号,則将每個定義中的“存在且非null”部分改為“存在”,即運算符僅用于測試變量是否存在。
path的值為:/home/tolstoy/mem/long.file.name
運算符 | 替換 |
${variable#pattern} | 若模式比對于變量值的開頭處,則删除比對的最短部分, 并傳回剩下的部分。 eg: ${path#} 結果:long.file.name |
${variable%pattern} | 若模式比對于變量值的結尾處,則删除比對的最短部分, 并傳回剩下的部分 eg: ${path%.*} 結果:/home/tolstoy/men/long.file |
${variable%%pattern} | 若模式比對于變量值的結尾處,則删除比對的最長部分, 并傳回剩下的部分。 eg:${path%%.*} 結果:/home/tolstoy/men/long |
位置參數:
位置參數 (positional parameter),指的是Shell腳本 的指令行參數(argument),同時也表示在Shell函數内的函數參數,其名稱是以單個的整數來命名。當整數大于9時,就以花括号({})括起來。
符号 | 含義 |
$# | 提供傳遞到Shell腳本或函數的參數總數 當是為處理選項和參數而建立循環時,會很有用。 |
$*, $@ | 一次表示所有的指令行參數 這兩參數可用來把指令行參數 傳遞給腳本或函數所執行的程式 |
“$*” | 将所有指令行參數視為單個字元串 等同于”$1 $2 ...“ $IFS的第一個字元用來作分隔字元,以分隔不同的值來建立字元串 |
"$@" | 将所有指令行參數視為單個的個體 即單獨字元串,等同于"$1" "$2" ...... 是将參數傳遞給其他程式的最佳方式,因這會保留 所有内嵌在每個參數裡的任何空白 |
名稱 | 作用 |
set | 調用此指令而未給予任何選項, 它會設定位置參數的值,并将之前 存在的任何值 丢棄 |
shift | 用來”截去(lops off)“來自清單的位置 參數,由左開始。 一旦執行shift,則$1的初始值會永遠消失, 取而是$2的舊值,$2的值,變成$3的舊值 還可接受一個可選的參數,即可指定一次要移動幾位 預設為1 |
特殊變量
$$變量可在編寫腳本時用來建立具有唯一性的檔案名(多半是臨時的)
算術運算符
與C類似
(3)退出狀态
退出的狀态值
exit指令
文法 :
exit [ exit- value]
用途:
從Shell腳本 傳回一個退出狀态給腳本的調用者
行為模式:
若沒有提供,則最後一個的執行指令的退出狀态作為預設的退出狀态。若即為所需,則在Shell腳本裡這樣寫:
exit $?
if-elif-else-fi語句
邏輯的NOT、AND與OR(均屬short-cut運算符)
表示邏輯否時的!放在管道(pipeline)前
test指令
test指令可處理Shell腳本裡的各類工作,産生的不是一般輸出,而是可使用的退出狀态。
文法:
test [ expression ]
[ [ expression ] ]
用途:
測試Shell腳本裡的條件,通過退出狀态傳回其結果。特别注意的是:第二種形式中,主括号根據字面意義逐字地輸入,且必須與括起來的expression以空白隔開。
行為模式:
test用來測試檔案屬性、比較字元串及比較數字
(4)case語句
(5)循環
for循環
while與until循環
break與continue
通過結合while、case、break及shift,可做些簡單的選項處理
getopts指令用法
文法:
getopts option_spec variable [ arguments ... ]
用途
簡化參數處理,并讓Shell腳本可輕松地比對于POSIX參數處理慣例
行為模式
(6)函數
(7)輸入/輸出、檔案與指令執行
Standard I/O
Standard input、Standard output、Standard error
使用read讀取行
read指令用法
文法:read [ -r ] variable ...
用途:将資訊讀入一個或多個Shell變量
主要選項:-r 【原始讀取,不作任何處理,不将行結尾處的反斜杠解釋為續行字元】
關于重定向
基本的輸入輸出重定向運算符: <、 >、 >>及|
額外的重定向運算符:
使用set -C搭配,防止檔案意外截斷的選項;執行set -C指令可打開Shell所謂的禁止覆寫(nocolbber)選項,當它處于打開狀态時,單純的>重定向遇到目标檔案已存在時,會失敗;>|運算符則可令noclobber選項失效。
提供行輸入(inline input)的<<與<<-:
使用program << delimiter,可在Shell腳本正文内提供輸入資料,這樣的資料叫作嵌入檔案(here document)。
printf指令:
文法: printf format-string [arguments ... ]
(8)波浪号展開與通配符
檔案名操作:~将使用者根目錄的符号型表示方式,改為實際的目錄路徑,可采用直接或間接的方式指定此程式的使用者。
*表示所有的檔案名
(9)引用
引用(quoting)是用來防止Shell将某些你想要的東西解釋成不同的意義。 三種引用的方式: 反斜杠轉義(\),用來告知Shell該字元即為字面上的意義。 單引号('...')強制Shell将一對引号之間的所有字元都看作其字面上的意義。Shell腳本會删除這兩個引号,隻單獨留下被括起來的完整文字内容。 雙引号(“...”)跟單引号類似,将括起來的文字視為單一字元串,不過,雙引号會确切地處理括起來文字中的轉義字元和變量、算術、指令替換。
(10)subShell與代碼塊
subShell:
是一群被括在圓括号裡的指令,這些指令會在另外的程序中執行。
當需讓一小組的指令在不同的目錄下執行時,可用該方法,不必修改主腳本的目錄,直接處理這種情況。
4. awk
指令行: awk [- F fs] [-v var=value ... ] 'program' [ -- ] \ [ var=value ... ] [ file(s) ](短程式在直接在指令行上提供) awk [ -F fs] [ -v var=value ...] -f programfile [ -- ] \ [ var=value ... ] [ file(s) ](較長的程式由委托-f選項指定)
--選項:特殊選項,指出awk本身已沒有更進一步的指令行選項,任何接下來的選項賭阿被程式使用。 -F選項:用來重新定義預設字段分隔字元,一般作為第一個指令行選項。 fs參數:是一個正規表達式,或是被提供作為下一個參數。 -v選項:須放在指令行上直接給定的任何程式之前,它們會在程式啟動之前以及處理任何檔案之前生效、在指令行程式之後的-v選項會被解釋為一個檔案名。
(1)awk程式模型
awk程式是一對以模式(pattern)與大括号框起來的操作(action)組合而成的,還會加上實作操作細節的函數(function)。針對每個比對于輸入資料的模式,操作會被執行,且所有模式都會針對每條輸入記錄而檢查。
(2)标量變量與數組變量
儲存單一值的變量叫做标量變量
數組變量:包含零到多個資料項,通過緊接着名稱的數組索引標明。awk允許在數組名稱之後,以方括号将任意數字或字元串表達式括起來作為索引。
(3)記錄與字段
在awk程式化模式中,通過輸入檔案隐含循環的每一次疊代,會處理單一記錄(record),通常是一行文本。記錄可進一步再分割為更小的字元串,叫做字段(field)。
記錄分隔字元(RS):gawk中RS可以是正規表達式,可提供比單一字元還長的長度。
eg:RS = "+"比對于字面上的一個加号,而RS = ":+"比對于一個或多個冒号,提供了更強大的規格。
字段分隔字元(FS):字段彼此是被比對字段分隔字元正規表達式(可在變量FS裡取得)的目前字元串值分隔。
字段可以特殊名稱$1、$2、$3、....、$NF供awk程式使用,字段引用無須是固定的,可轉換(通過截斷)為整數值。
特殊字段名稱$0引用目前記錄,初始值是從輸入流中讀取,且記錄分隔字元不是記錄的一部分。引用到0到NF範圍以上的字段編号是不會有錯的,它們會傳回空字元串,且不會建立新字段,除非指定值給它們。
(4)模式與操作
模式:由字元串/或數值表達式建構而成,當計算出目前輸入記錄的值為非零(真),則實行結合性的操作
(5)語句
連續執行:
條件式執行:
重複執行:
使用者控制的輸入getline
(6)字元串函數
length(string):用來傳回字元串string的長度
子字元串提取:
substr(string, start, len):提取子字元串的函數;
字母大小寫轉換:
tolower(string):将所有字母改為小寫;
toupper(string):将所有字母改為大寫;
字元串查找:
index(string,find):查找string裡是否有字元串find,傳回string裡的find字元串的起始位置;若string裡找不到find,則傳回0;
字元串比對:
match(string,regexp):将string與正規表達式regexp比對,若比對,則傳回比對string的索引,不比對,則傳回0。
字元串替換:
sub(regexp,replacement,target):将target與正規表達式regexp進行比對,将最左邊最長的比對部分替換為字元串replacement;返替換的數目,若活力第三個參數,則預設值為目前記錄$0.
gsub(regexp,replacement,target):與sub有些類似,不過它會替換所有比對的字元串。
注意:這兩個函數的調用過程中,每個replacement裡的字元&都會被替換為target中與regexp比對的文本,使用\&可關閉這一功能,且請刻若要在引号字元串裡使用它時,以雙反斜杠轉義它。
字元串分割
split(string, array, regexp):将string切割為片段,并存儲到array裡的連續元素。
字元串重建
join():
字元串格式化
sprintf(format, expressoin1, expression2, ... ):會傳回已格式化的字元串作為其函數值