第一部分數組:html
bash腳本編程:
變量:變量名 ,命名的命名空間
數組:連續的多個獨立內存空間;每一個內存空間至關於一個變量;
數據元素的引用:數組名[索引]前端
bash 4.0+之後版本支持二種類型:
傳統數組(基本數組):索引爲數字,從0開始編號;
declare -a ARRAY_NAME
關聯數組:索引能夠自定義,可使用任意字符串作索引;
declare -A ARRAY_NAME正則表達式
支持稀疏格式(指賦值第一個後,可隨意跳到第3個或四、7等,可不連續)shell
數組元素的賦值方式:
(1) 一次只賦值一個元素
array[index]=value
(2) 一次賦值所有元素
array=("val1" "val2" ...) #從索引0,1,2….開始,順序的
(3) 指定索引進行賦值
array=([0]="val1" [3]="val2") #區別指名索引,稀疏格式
(4) read -a array #基於,多個一個元素在一個數組中express
示例:將變量tom ,jerry,ben保存在一數組arrary當中,利用array數組apache
下面加索引的方式。進行調用編程
引用元素:${array[index]}vim
長度(數組的長度):${#array[*]}, ${#array[@]}數組
練習:利用bash生成10個隨機數值,保存於數組中;要此些數組排序
$RANDOM (從0至32767) 示例:echo $RANDOM(注意必須是大寫)bash
第二部分:Sed命令
grep, sed, awk
grep: 文本搜索工具;egrep, fgrep
sed: stream editor, 流編輯器;
awk(gawk):文本格式化工具,報告生成器
第一:sed運行方式
sed一次讀取一行。能夠是指定範圍的行,或者表達式。
一次讀一行後運行在本身的模式空間(pattern space),針對文本進行
處理。判斷是否符合判斷條件進行編輯操做,符合條件處理後輸出
到屏幕當中。即打印模式空間(默認)不論是否成功。
第二:sed命令:
1) 基本正則表達式元字符:
字符匹配:., [], [^]
次數匹配:*, \?, \+, \{m,n\}, \{n\}
位置錨定:^, $, \<, \>
分組及引用:\(\), \1, \2, ...
多選一:a|b|c
vim編輯中文本的查找替換:
地址定界s/要查找的內容/替換爲的內容/
要查找的內容:可以使用正則表達式
替換爲的內容:不支持正則表達式,但支持引用前面正則表達式分組中的內容
地址定界:%, startline,endline
2)語法
語法:sed [OPTION]... {script} [input-file]...
工做機制:每次讀取一行文本至「模式空間(pattern space)」中,在模式空間中完成處理;將處理結果輸出至標準輸出設備;
A) Option選項
-r: 支持擴展正則表達式;
-n: 靜默模式; (指只打印靜默默認的行,沒有要求輸出不作輸出操做)
-e script1 -e script2 -e script3:指定多腳本運行;
-f /path/to/script_file:從指定的文件中讀取腳本並運行;
-i: 直接修改源文件;(默認sed不會對源文件做操做)
B)腳本
其中腳本包括地址定界和編輯命令二個功能
地址定界: (類型VIM)
#: 指定行; :# 指定行
$: 最後一行;
/regexp/:任何可以被regexp所匹配到的行;
\%regexp%:同上,只不過換做%爲regexp邊界符;
/regexp/| :
\%regexp%| :匹配時忽略字符大小寫;
startline,endline:
#,/regexp/:從#行開始,到第一次被/regexp/所匹配到的行結束,中間的全部行;
#,#
示例:sed ‘1,4d’ /etc/fstab 刪除1至4行
/regexp1/,/regexp2/:從第一次被/regexp1/匹配到的行開始,到第一次被/regexp2/匹配到的行結束,中間的全部行;
#,+n:從#行開始,一直到向下的n行;
first~step:指定起始行,以及步長;
1~2, 說明從1開始,步進爲2,這樣爲1,3,5,7.。。。奇數行
2~2 ,說明 從2開始,步進爲2,這樣爲2,3,4,6,8 。。。偶數行
sed的編輯命令
d: 刪除模式空間中的行;
示例:不顯示/etc/fstab中以UUID開始的行
示例 sed ‘1,4=’ /etc/fstab
示例 sed '/^UUID/a \newline' /etc/fstab 同時也能夠轉意再添加一行
sed '/^UUID/a \newline \n secondline' /etc/fstab
i \text:插入text,支持\n實現多行插入; (在符合條件行以前)
p: 打印模式空間中的行; (默認狀況下,sed會打印模式空間的行,當
知足條件時會打印二行)
針對靜默空間的行採用-n選項
s/regexp/replacement/:替換由regexp所匹配到的內容爲replacement;
g: 全局替換;
w /path/to/somefile:把指定的內容另存至/path/to/somefile路徑所指定的文件中;
示例:將奇數行保存至/tmp/fstab.odd文件當中
r /path/from/somefile:在文件的指定位置插入另外一個文件的全部內容,完成文件合併;
示例:將/etc/issue文件中插入到第五行後,完成文件合併
練習:
(1) 刪除/boot/grub/grub.conf文件中全部行的行首的空白字符;
sed 's/^[[:space:]]\+//' /boot/grub/grub.conf #//替換爲空 全文件查找不用使用定界
可在s前填加地址定界,例如第10行。。。
刪除空白行
sed ‘/^$/d’ /etc/grub2.cfg
(2) 刪除/etc/fstab文件中全部以#開頭,後跟至少一個空白字符的行的行首的#和空白字符;
sed 's/^#[[:space:]]\+//' /etc/fstab #\+匹配次數1
(3) 把/etc/fstab文件的奇數行另存爲/tmp/fstab.3;
sed '1~2w /tmp/fstab.3' /etc/fstab
(4) echo一個文件路徑給sed命令,取出其基名;進一步地,取出其路徑名;
取基名:echo "/etc/sysconfig/network-scripts/" | sed 's@^.*/\([^/]\+\)/\?$@\1@'
取路徑名:echo "/etc/sysconfig/network-scripts/" | sed 's@[^/]\+/\?$@@'
sed命令另外一個稱做"hold space"的內存空間:保持空間
pattern space這加工廠,hold space爲倉庫。用的時候還能夠取回。
只可以在pattern space編輯。
高級命令:
h:用模式空間中的內容覆蓋保持空間的內容;
H:把模式空間中的內容追加至保持空間中內容的後面;
g:從保持空間中取到其內容,並將其覆蓋模式空間中的內容;
G:從保持空間中取到其內容,並將其追加在模式空間中的內容的後面;
x:把保持空間和模式空間中的進行交換;
n:讀取匹配到的行的下一行至模式空間;(會覆蓋模式空間中的原有內容);
N:讀取匹配到的行的下一行至模式空間,追加在模式空間中原有內容的後面;
d:刪除模式空間中的內容;
D:刪除多行模式空間中的首行;
注意:命令功能可以使用!取反(針對地址取反);分號可用於分隔腳本;
示例:
sed '1,3!d' /etc/fstab 表示1至3行以外行刪除掉,這裏針對地址定界取反
sed 'G' /etc/issue: 在文件中的每行後方添加空白行; 由於模式空間爲空
sed '$!d' /etc/fstab:保留最後一行; $表示最後一行
sed '/^$/d;G' /etc/issue: 保證指定的文件每一行後方有且只有一個空白行;
(若是前爲空白行刪除,非空白行後面添加一個空白行)
^$爲空白行
sed 'n;d' /etc/issue:保留奇數行; 從外命令分號分隔開(每讀的下一行爲偶數行)
當讀1行第時,這時第2行會刪除以此類推)
sed -n '1!G;h;$p' /etc/issue $p打印最後一行,第一行不作get,不從
保存空間取內容。示例:左側第一排爲輸入文件,中間一排爲模式空間,第三排
爲保存空間。輸出爲4,3,2,1;功能:逆序顯示文件內容
-n沒有要求輸出,不作輸出操做
tac 命令用於逆向顯示
sed '$!N;$!D' /etc/issue 顯示最後一行
sed命令:
-e 'script' -e 'script'
'script;script;script'
script
script
script
-f /path/from/script
第三部分:AWK
1)定義及工做方式
AA:定義
首先awk爲c語言風格
awk:
grep, sed, awk (文件格式化輸出工具)
grep: 文本過濾器
sed: 行編輯器
awk: 報告生成器(早期在Unix版本)
AWK a.k.a Aho, Weinberger, Kernighan
Gnu AWK, gawk(awk是指向gawk的連接)
ls –l `which awk`
awk功能相比sed更增強大支持if語句、條件判斷、數組、自定義函數等功能
BB:工做模式
一次讀一行到本身的命名空間,不對每行作操做只針對符合條件的行進行編輯,
進行地址定界。在awk裏面稱爲模式。
將一行文本信息,按照用戶指定的格式或分隔符切成n片。保存到awk指定的
變量當中。引用整行用$0,引用某段利用$1,$2。。。進行引用
2)基本語法
awk [options] 'program' file file ...
awk [options] 'PATTERN{action}' file file ...
awk的相似cut,每一個 program可分解爲pattern{action}
內置一次讀一行(循環處理每一行之意),其中action經常使用
的包括print(簡單輸出)、printf(格式化輸出)
示例: 顯示/etc/passwd以冒號分隔的第一段
awk -F: '{print $1}' /etc/passwd
-F CHAR:輸入分隔符 ‘{ }’ 表示引用本身的腳本,$1第一字段
加$表示引用字段
A、awk的輸出
print item1, item2,...
itme一、item2可爲字符、也能夠爲字符串(必須雙引號)
要點:
(1) 各項目之間使用逗號分隔,而輸出時則使用輸出分隔符分隔;
各項目之間輸出以空格分隔,逗號有多個條之意
若是$1,$3之間爲空後,將二個項目相聯
(2) 輸出的各item能夠字符串或數值、當前記錄的字段、變量或awk的表達式;
數值會被隱式轉換爲字符串後輸出;
(3) print後面item若是省略,至關於print $0;輸出空白,使用pirnt "";
B、awk的變量
內置變量,自定義變量,注意內部引用變量不須要$
2.1 內置變量 (awk自帶的)
FS:Field Seperator, 輸入時的字段分隔符
# awk 'BEGIN{FS=":"}{print $1,$7}' /etc/passwd
RS:Record Seperator, 輸入行分隔符
OFS: Output Field Seperator, 輸出時的字段分隔符;
ORS: Outpput Row Seperator, 輸出時的行分隔符;
NF:Numbers of Field,每一行的字段數 :默認以空格進行統計。無空格爲1
NR:Numbers of Record, 行數/號;全部文件的一併計數; 進行行統計
示例:awk ` (printf NR,$0)’ /etc/fstab /etc/issue
若是NR前加$NR表示讀取字段數的值(原文件左側
awk '{print $NF}' /etc/grub2.cfg 以最後一段爲4(該語句含義打印第四4個字段,
若是是其它字段則變化,實際爲打印最後一個字段的值)
ARGV:數組,保存命令自己這個字符,awk '{print $0}' 1.txt 2.txt,意味着ARGV[0]保存awk,
ARGC: 保存awk命令中參數的個數;
FILENAME: awk正在處理的當前文件的名稱;
2.2 可自定義變量
-v var_name=VALUE -v表示給一個變量賦值
變量名區分字符大小寫;
(1) 能夠program中定義變量;
(2) 能夠命令行中經過-v選項自定義變量;
示例:定義變量test,在打印時引用變量,加到輸入字段輸出
示例:打印每一個及最後一個字段(冒號分隔)
awk -F: '{print $1,$NF}' /etc/passwd 命令可修改成
awk -v FS=: '{print $1,$NF}' /etc/passwd 其中FS爲變量,同時
FS爲內置輸入時的分隔符。這裏爲:(冒號)
# awk -v FS=: -v OFS=# '{print $1,$NF}' /etc/passwd
使用OFS爲輸出時的分隔符,這樣字段1和最後一個字段時間以#號分隔
三、awk的printf命令(f表明format ,可定義相應的格式)
命令的使用格式:printf format, item1, item2,...
每一個itme都會對應相應的format
要點:
(1) 要指定format;
(2) 不會自動換行;如需換行則須要給出\n
(3) format用於爲後面的每一個item指定其輸出格式;
format格式的指示符都%開頭,後跟一個字符:
%c: 顯示字符的ASCII碼;
%d, %i: 十進制整數;
%e, %E: 科學計數法顯示數值;
%f: 顯示浮點數;
%g, %G: 以科學計數法格式或浮點數格式顯示數值;
%s: 顯示字符串;
%u: 顯示無符號整數;
%%: 顯示%自身;
修飾符:
#:顯示寬度 3表明三個字符的寬度
-:左對齊
+:顯示數值的符號
.#: 取值精度
示例:
awk -F: '{printf "UID:%d\n",$3}' /etc/passwd
以UID:xxxx;顯示%d表示十進制數,\n表示換行,將$3放到
format中進行顯示
將修飾符添加到%d前端例如 %10d表示寬度爲10,%.10d表示
10個字符,前會以0補充。(默認靠右對齊如%-10d 左對齊)
四、awk輸出重定向 (未講解)
print items > output-file
print items >> output-file
print items | command
示例:將輸出保存到/tmp/51cto/awkout文件中
特殊文件描述符:
/dev/stdin: 標準輸入
/dev/stdout: 標準輸出
/dev/stderr: 錯誤輸出
五、awk的操做符
算術操做符:
x+y
x-y
x*y
x/y
x**y, x^y 求次方
x%y 取模
-x:負值
+x:轉換爲數值
字符串操做符:鏈接 不須要任何,不可以使用逗號,
賦值操做符:
=
+=
-=
*=
/=
%=
^=
**=
++ 自加
-- 自減
若是模式自身是=號,要寫爲/=/
比較操做符:
<
<=
>
>=
==
!=
~:模式匹配,左邊的字符串可以被右邊的模式所匹配爲真,不然爲假;
!~:
邏輯操做符:
&&: 與
||:或
條件表達式: (雙分支語句)
selector?if-true-expression:if-false-expression
selector是個挑選器,若是真執行if-true-express分支,假執行if-false分支
示例:
# awk -F: '{$3>=1000?utype="common user":utype="admin or system user";print $1,"is",utype}'
/etc/passwd
函數調用: (支持內部或外部函數)
function_name(argu1,argu2) #以函數名加用戶參數的形式指定。
後續進行awk的pattern和Action
六、模式
awk pattern支持的五種類型
(1) Regexp: 格式爲/PATTERN/ 模式匹配到的行進行處理,不然不進行處理
僅處理被/PATTERN/匹配到的行;
示例 awk '{print $3}' /etc/fstab
以UUID開始的行
(2) Expression: 表達式,其結果爲非0或非空字符串時知足條件;
僅處理知足條件的行; (利用比較操做符)
示例:awk -F: '$3>=1000 {print $1,$3}' /etc/passwd
awk -F: '$NF~/bash$/ {print $1,$NF} ' /etc/passwd
$NF表示結尾 $NF表明最後一個字段
~:模式匹配,左邊的字符串可以被右邊的模式所匹配爲真,不然爲假;
!~
bash$表示以bash結尾
awk -F: '$NF!~/bash$/ {print $NF} ' /etc/passwd 最後字段非bash結尾
(3) Ranges: 行範圍,此前地址定界,
NR 行號
僅處理範圍內的行
awk -F: 'NR>=15 && NR<=20 {print $1,$NF}' /etc/passwd 輸出15至20行的內容
僅在awk命令的program運行以前(BEGIN)或運行以後(END)執行一次;
示例:在運行以後打印一行」=====usernme====shell====」
Begin和End之間或以後使用相應變量,或提示信息等
(5) Empty:空模式,匹配任意行;(若是未指定行說明是全部行)
七、經常使用的action
(1) Expressions 表達式 :比較、算術表明式等,多個用分號分隔
(2) Control statements 控制語句
(3) Compound statements 組合語句
(4) input statements 輸入語句
(5) output statements 輸出語句 print printf
八、控制語句
8.1 if-else
格式:if (condition) {then body} else {else body} 注意:條件是小括號
# awk -F: '{if ($3>=500) {print $1,"is a common user"} else {print $1, "is an admin or system user"}}' /etc/passwd
# awk '{if (NF>=8) {print}}' /etc/inittab #當字段數大於打印整行內容 NF字段數,無else直接 print(單分支)
NR行號
# awk '{if (NF>=8) {print $0} else {print NR,$0}}' /etc/inittab #大於8顯示行號,不大於8不顯示行號
判斷用戶id與組id是否一致
# awk -F: '{if ($3==$4) {print $1, "good user"}}' /etc/passwd
8.2 while (通常用於針對某字段作相似處理)
格式:while (condition) {while body} 條件爲真執行
# awk '{i=1; while (i<=NF){printf "%s ",$i;i+=2};print ""}' /etc/inittab
顯示奇數字段,print可以換行
# awk '{i=1; while (i<=NF){if (length($i)>=6) {print $i}; i++}}' /etc/inittab
字段串長度大於6顯示
length()函數:取字符串的長度
%s: 顯示字符串;
8.3 do-while循環
至少執行一次,無論條件是否爲真或假
格式:do {do-while body} while (condition)
8.4 for循環
格式:for (variable assignment; condition; iteration process) {for body}
# awk '{for (i=1;i<=NF;i+=2){printf "%s ",$i};print ""}' /etc/inittab 顯示奇數字段 # awk '{for (i=1;i<=NF;i++){if (length($i)>=6) print $i}}' /etc/inittab
for循環可用來遍歷數組元素:
語法:for (i in array) {for body}
8.5 case語句
語法:switch (expression) {case VALUE or /RGEEXP/: statement1;... default: stementN}
都不知足執行default語句
8.6 循環控制
break 提早終止循環
continue 提早終止本輪循環 針對字段
8.7 next 【針對行】
提早結束對本行的處理進而提早進入下一行的處理;
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd #顯示奇數用戶的id # awk -F: '{if(NR%2==0) next; print NR,$1}' /etc/passwd
九、數組
傳統數組:Index編號從1開始;
關聯數組:
array[index-expression]
index-expression: 可使用任意字符串; 若是某數組元素事先不存在,那麼在引用時,
awk會自動建立此元素並將其初始化爲空串;所以,要判斷某數組是否存在某元素,
必須使用「index in array」這種格式;
A[first]="hello awk"
print A[second]
要遍歷數組中的每個元素,須要使用以下特殊結構:
for (var in array) {for body} #var保存的是array的每個索引
其var會遍歷array的索引;
示例: 如附字符串時須要在數組中以雙引號 test[「 字符串」]
利用for循環語句輸出
# awk 'BEGIN{test["mon"]="monday";test["tue"]="tuesday";for (i in test){print test[i]}}'
state[LISTEN]++
state[ESTABLISHED]++
NF字段數;$NF最後一個字段
# netstat -tan | awk '/^tcp/{++state[$NF]}END{for (s in state) {print s,state[s]}}'
顯示連接的個數,^tcp協議類型,state數組,將狀態保存到數組當中,當有一個元素時
加1用++表示,awk自動循環。這裏數組state當中包括二種listen的數量和establised數量。
最後用end在最後面一次輸出相應的值
# awk '{ip[$1]++}END{for (i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
統計每一個IP地址請求次數,須要利用httpd服務
AA:啓動httpd服務的80端口
BB:編輯 vim /var/www/html/index.html, 隨意輸入內容
CC:運行 ab -n 10000 -c 100 http://192.168.6.184/index.html 模擬請求
ab爲apache測試工具
DD:查看/var/log/httpd/access_log目錄內容
顯示客戶端對服務端 的請求
EE:利用輸出語句,彙總相關信息
統計每一個IP地址請求次數
刪除數組元素:
delete array[index]
十、awk的內置函數
split(string,array[,fieldsep[,seps]]):
功能:將string表示的字符串以fieldsep爲分隔符進行切片,
並切片後的結果保存至array爲名的數組中;數組下標從1開始;
root:x:0:0::/root:/bin/bash
user[1]="root", user[2]
此函數有返回值,返回值爲切片後的元素的個數
# netstat -tn | awk '/^tcp/{lens=split($5,client,":");ip[client[1]]++}END{for (i in ip) print i,ip[i]}'
顯示第五個這段冒號前的地址,保存到數組client當中進行統計
length(string)
功能:返回給定字串的長度
substr(string,start[,length])
功能:從string中取子串,從start爲起始位置爲取length長度的子串;
博客:sed和awk的使用