Shell腳本之awk文本編輯器語法(二) ---------------------------------- 流程控制 分支結構 (一) if (條件) 動做 if (條件) {動做1;動做2} 如: # awk -F: '{if ($1 == "root")print $1}' /etc/passwd awk -F: '{if ($1 == "root"){print $1;print $7}}' /etc/passwd (二) if (條件1) 動做1 else 動做2 如: # awk -F: '{if ($1 == "root") print $1; else print $6}' testfile # awk -F: '{if ($1 == "root") {print $1} else print $6}' testfile 上面兩個命令是等價的,要麼用分號隔開,表示第一個動做體的結束,要麼將動做體用大括號定位範圍 (三)if (條件1) 動做1 else if (條件2) 動做2 else if (條件2) 動做3 else 動做4 如: # awk -F: '{if ($1=="root")print $1;else if($1=="bin")print $3;else if($1=="myuser")print $7}' testfile (四) 條件 ? 動做1:動做2 expr ? action1:action2 如: # awk -F: 'AA=($3>=500?$3:"system_user"){print $1"\t"$3"\t"AA}' testfile root 0 system_user bin 1 system_user myuser 501 501 ---------------------------------------------------------- 讀前處理和讀後處理 如: # awk 'BEGIN{i=1} {i++} END{print i}' /etc/passwd # awk -F: 'BEGIN{print NR,NF} END{print NR,NF}' /etc/passwd 0 0 46 7 # awk -F: 'BEGIN{sum=0} {sum=sum+NF}END{print sum}' /etc/passwd 322 # awk -F: 'BEGIN{sum=0} {sum+=NF}END{print sum}' /etc/passwd 322 BEGIN塊能夠獨立使用,不須要引入文件 # awk 'BEGIN{i=1;while(i<10) {print i;i++}}' 1 2 3 4 5 6 7 8 9 ------------------------------------------------------------- 循環語句 (一) while (條件) { 動做 條件運算 } 如: # awk -F: '{while($3<3) {print $3,$1;$3++}}' /etc/passwd 0 root 1 root 2 root 1 bin 2 bin 2 daemon (二) do { 動做 條件運算 } while (條件) 如: # awk 'BEGIN{i=5;do{print i;i++}while(i<10)}' 5 6 7 8 9 (三)for (預置;條件;遞增) { 動做 } 如: # awk 'BEGIN{for (i=1;i<5;i++) print i}' 1 2 3 4 (四) 循環for嵌套 如: # awk 'BEGIN{for (i=1;i<3;i++) {for (j=1;j<=3;j++) print i,j}}' 1 1 1 2 1 3 2 1 2 2 2 3 # awk 'BEGIN{OFS="";for (i=1;i<=9;i++) {for (j=0;j<=9;j++) {for (n=0;n<=9;n++) print i,j,n}}}' 使用嵌套的for循環,打印100-999之間的數 # awk -F: '{for(x=NF;x>0;x--)print $x}' testfile 逆序輸出 ------------------------------------------------------------ 輸出樣式 # awk -F: '{printf "%-10s %-7d %s\n",$1,$3,$7}' testfile root 0 /bin/bash bin 1 /sbin/nologin myuser 501 /bin/bash 命令分析: %s是字符類型,%d數值類型 printf默認是不輸出換行的因此要加\n(printf和print不一樣,print默認每輸出一行進行換行) 10和7是偏移量 默認是右對齊,全部加個- 就是左對齊,就是把不足的位數用空格填充 注意:格式與輸出列之間要有逗號 --------------------------------------- 跳轉語句 break 跳出循環 # awk 'BEGIN {for(x=1;x<5;x++) {if (x==3) break;print x }}' 1 2 continue 在達到循環底部以前終止當前循環 重新開始下一次循環 # awk 'BEGIN {for(x=1;x<5;x++) {if (x==3) continue;print x }}' 1 2 4 next 讀入下一行 同時返回腳本頂部 這樣能夠避免對當前行執行其餘操做 # awk -F: 'NR > 5 {next} {print $1} END {print NR}' /etc/passwd root bin daemon adm lp 46 exit 使讀取動做終止 並將控制移動到END,若是沒有END則終止腳本 # awk -F: 'NR > 5 {exit} {print $1} END {print NR}' /etc/passwd root bin daemon adm lp 6 -------------------------------------------------------------------- 函數 轉換函數,轉換成整數 如: # awk 'BEGIN{print int(3.934)}' 3 隨機數函數 rand() srand() rand() 取值 0 > r > 1 之間 默認的種子是系統時間 精確到秒 srand()取值 0 > r > 1 之間 能夠指定種子來影響rand()取值數 默認是系統時間 精確到秒 echo $RANDOM 如: # awk 'BEGIN{print int(rand()*100)}' 23 # awk 'BEGIN{srand(123);print int(rand()*100)}' 74 # awk -v a=$RANDOM 'BEGIN{print a}' 22059 字符串函數 substr(s,x,y) 返回字符串s中從位置x起至y的子串,若是沒有給出y,則從x開始到結束 如: # awk 'BEGIN{aa="abcdefghi";print substr(aa,3,4)}' cdef # awk 'BEGIN{aa="abcdefghi";print substr(aa,1)}' abcdefghi 大寫小寫函數 tolower() 小寫函數 toupper() 大寫函數 sprintf() 自己並不能打印,作格式轉換,將數字轉換成ASCII字符 # awk 'BEGIN{for(i=97;i<=122;++i)print toupper(sprintf("%c",i))}' # awk 'BEGIN{for(i=97;i<=122;++i)print tolower(sprintf("%c",i))}' 字符串長度 length() 若是沒有給定字符串則使用$0 # awk 'BEGIN{print length("abcdefghi")}' 9 # awk '{print length()}' /etc/passwd gsub(/abc/,"ABC",x) 全局字符串替換,從x中用匹配的abc正則替換成ABC # awk 'BEGIN{aa="abcxyzabcxyzabc";gsub(/abc/,"ABC",aa);print aa}' ABCxyzABCxyzABC 系統交互輸入函數——getline (等同於shell中的read -p "strings" var ) 如: # awk -F: 'BEGIN{printf "sss: ";getline;for(i=1;i<=$0;i++) print i}' sss: 4 1 2 3 4 使用getline函數將輸入值賦給變量 # awk -F: 'BEGIN{printf "haoren: ";getline NUM;for(i=1;i<=NUM;i++)print NUM,i}' haoren: 5 5 1 5 2 5 3 5 4 5 5 從文件中讀入 #awk -F: 'BEGIN {while (getline < "/etc/passwd" > 0) print $3"\t"$1}' getline < "/etc/passwd" 從文件中讀入,每次讀取一行,默認狀況下讀取的次數等於awk自身引入文件的行數 > 0 測試讀取的返回值,成功返回1,失敗返回-1,0文件末尾 從命令輸出中輸入 [root@stu254 ~]# awk 'BEGIN {"uname -a"|getline ;print $3}' 2.6.18-53.el5 system(command)——引入系統命令,系統命令要用""引發來 如: # awk 'BEGIN{if(system("mkdir mulu1") != 0) print "error"}' # awk 'BEGIN{if(system("mkdir mulu1") != 0) print "error"}' mkdir: 沒法建立目錄"mulu1": 文件已存在 error awk腳本—— -f 腳本開頭使用 #!/bin/awk -f 如:使用awk腳本添加用戶 #!/bin/awk -f { system("useradd "$1";echo "$2"|passwd --stdin" $1) } # cat user.txt myuser222 123123 myuser333 456456 # ./useradd.awk user.txt 更改用戶 myuser222 的密碼 。 passwd: 全部的身份驗證令牌已經成功更新。 更改用戶 myuser333 的密碼 。 passwd: 全部的身份驗證令牌已經成功更新。