linux三劍客之awk +for循環+while循環


for循環

  格式:
 方式一:
for 變量 in 數組
do # for循環開始

# for循環體

done # for循環結束  
         方式二:
           for 變量 in 數組 ; do for循環體1; for循環體2; for循環體3 ; done

作用:

1、作用是遍歷數組,對數組中的所有元素進行處理
2、將數組中存儲的元素取出來使用(計算,做特殊處理)

案例:

循環出數組

for i in ${array7[*]}
do

echo $i

done

[root@localhost ~]# for i in ${array7[*]}; do echo $i; echo "xxxx" ; done

awk

awk基礎

1、什么是awk,主要作用是什么?

awk 主要用來處理文件,將文本按照指定的格式輸出。其中包含變量,循環以及數組。

2、awk的格式

awk [選項] '匹配規則和處理規則' [處理文本路徑]
[root@localhost ~]# awk -F: '{print $1}' /etc/passwd

標准輸出 | awk [選項] '匹配規則和處理規則'
[root@localhost ~]# cat /etc/passwd | awk -F: '{print $1}'
       
       
   匹配規則:

1、字符串
2、正則表達式

處理規則:

BEGIN{} : BEGIN是在awk處理文本之前運行
// : 使用的匹配規則
{} :循環(每次只處理一行數據)
END{} :當所有的處理全部執行完畢之后,執行END中的相關操作

案例

 案例:

案例1:把/etc/passwd中的包含root的行打印出來
[root@localhost ~]# awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

案例2:把/etc/passwd中以root開頭的行打印出來
[root@localhost ~]# awk -F: '/^root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash

案例3:將/etc/passwd中匹配第三列和第五列的數據

[root@localhost ~]# awk -F: '{print $5,$3}' /etc/passwd

案例4:打印以root或者ntp開頭的行的解析器

[root@localhost ~]# awk -F: '/^root|^ntp/{print $7}' /etc/passwd
[root@localhost ~]# awk -F: '/^(root|ntp)/{print $7}' /etc/passwd

awk的工作原理

 (1)awk會接收一行作為輸入,並將這一行賦給awk的內部變量$0,每一行也可稱為一個記錄,行的邊界是以換行符作為結束(表明:awk是一行一行的去處理文本的)
(2)然后,剛剛讀入的行被以:為分隔符分解成若干字段(或域),每個字段存儲在已編號的變量中,編號從$1開始,最多達100個字段
注意:如果未指定行分隔符,awk將使用內置變量FS的值作為默認的行分隔符,FS默認值為空格,如果說要指定分隔符,需要使用-F參數或者重新定義FS變量
(3)使用print函數打印,如果$1$3之間沒有逗號,它倆在輸出時將貼在一起,應該在$1,$3之間加逗號,該逗號與awk的內置變量OFS保持一致,OFS默認為空格,於是以空格為分隔符輸出$1$3
我們可以指定:awk -F: 'BEGIN{OFS="-"}{print $1,$3}' /etc/passwd

(4)輸出之后,將從文件中獲取另一行,然后覆蓋給$0,繼續(2)的步驟將該行內容分隔成字段。。。繼續(3)的步驟
該過程一直持續到所有行處理完畢

awk中的變量

 $0表示文本中的所有字段
NR: 記錄號(行號)
NF: 保存記錄的字段數,$1,$2...$100(最后一列)
FS: 輸入字段分隔符,默認空格
OFS:輸出字段分隔符

案例

案例:

案例1:輸出/etc/passwd中的所有內容包括行號。
[root@localhost ~]# awk -F: '{print NR,$0}' /etc/passwd

案例2:要求把第7行之后的內容輸出出來,包括行號。
[root@localhost ~]# awk -F: 'NR > 7{print NR,$0}' /etc/passwd

案例3:要求輸出第7行之后的內容且第14行之前的內容輸出出來,包含行號
[root@localhost ~]# awk -F: 'NR > 7 && NR < 14{print NR,$0}' /etc/passwd

案例4:由案例3,要求輸出每行的UID增加1
[root@localhost ~]# awk -F: 'NR>7&&NR<14{print $3,$3+1}' /etc/passwd

案例5:要求輸出倒數第3列
[root@localhost ~]# awk -F: '{print $(NF-2)}' /etc/passwd

案例6:要求不使用-F參數,以:分割,並輸出第3列和第5列
[root@localhost ~]# awk 'BEGIN{FS=":"}{print $5,$3}' /etc/passwd

案例7:要求實驗證明-F FS的優先級

[root@localhost ~]# awk -F/ 'BEGIN{FS=":"}{print $7,$3}' /etc/passwd

證明得出-F參數的優先級小於FS變量的優先級

案例8:要求以:分割,並輸出第3列和第5列,第三列和第五列之間使用+號分割
[root@localhost ~]# awk -F: 'BEGIN{OFS="+"}{print $3,$5}' /etc/passwd

注:所有的變量的定義都應該放在BEGIN里面

案例9:將/etc/nginx/nginx.conf中的所有的詞的個數

格式化輸出



================print函數===================
date | awk '{print "月:",$2,"\n年:",$1}'
月: 09
年: 2020

awk -F: '{print "用戶名:",$1,"用戶id:",$3}' /etc/passwd

================printf函數===================
awk -F: '{printf "用戶名:%s 用戶id:%s\n",$1,$3}' /etc/passwd
awk -F: '{printf "|%-15s| %-10s| %-15s|\n", $1,$2,$3}' /etc/passwd

%s 字符類型
%d 數值類型
占15格的字符串
- 表示左對齊,默認是右對齊
printf默認不會在行尾自動換行,加\n

案例

 案例:

案例1:要求輸出第1列和最后一列,排版整齊
[root@localhost ~]# awk -F: '{printf "%-16s %s \n",$1,$NF}' /etc/passwd
           

操作模式

 1、正則模式

awk -F: '/^xxx/' /etc/passwd

2、比較模式

> <

awk -F 'NR > 7' /etc/passwd

3、條件模式

awk -F 'NR > 7' /etc/passwd

4、算數運算

awk -F '{print $3,$3+1}' /etc/passwd

5、范圍模式

[root@localhost ~]# awk -F: '/root/,/ftp/{print $1}' /etc/passwd

流程控制

if判斷

單分支
if () {}

雙分支
if () {} else {}

多分支
if(){} else if() {} else{}

案例:

案例1:打印奇數行的數據
[root@localhost ~]# awk -F: '{if( NR % 2 ){print NR,$0}}' /etc/passwd

案例2:打印偶數行的數據
[root@localhost ~]# awk -F: '{if( NR % 2 == 0 ){print NR,$0}}' /etc/passwd
[root@localhost ~]# awk -F: 'NR%2==0{print $0}' /etc/passwd

注:單分支情況下是可以省略if,多分支情況下不能省略

案例3:要求打印出偶數行中的包含bash的行
[root@localhost ~]# awk -F: '/bash/{if(NR%2==0){print NR,$0}}' /etc/passwd

案例4:要求在奇數行前輸出奇數,偶數行前輸出偶數
[root@localhost ~]# awk -F: '{if(NR%2){printf "奇數行:%s\n",$0}else{printf "偶數行:%s\n",$0}}' /etc/passwd

案例5:在前7行前加7, 前14行前加14,其他原樣輸出
[root@localhost ~]# awk -F: '{if(NR<=7){printf "7 %s \n",$0}else if (NR<=14){printf "14 %s \n",$0}else{print $0}}' /etc/passwd

for循環+awk

 for循環

for (變量 in 數組) {語句}

for (變量;條件;表達式){語句}

知識儲備:

++ 每次加1
-- 每次減1

案例:

案例1:要求統計以#開頭的行中包含的詞的格式

[root@localhost ~]# egrep '^ *#' /etc/fstab | egrep -o "[a-zA-Z0-9]+" | awk '{arr[$1]++}END{for(i in arr){printf "%-20s %d\n",i,arr[i]}}'

案例2:輸入一個文件路徑,要求打印出它的數字權限(不允許使用stat)

[root@localhost ~]# ll [路徑] | awk 'BEGIN{FS=""}{if($2=="r"){u=u+4} if($3=="w"){u=u+2} if($4=="x"){u=u+1} if($5=="r"){g=g+4} if($6=="w"){g=g+2} if($7=="x"){g=g+1} if($8=="r"){o=o+4} if($9=="w"){o=o+2} if($10=="x"){o=o+1}}END{print u,g,o}'

 

while循環

while循環

while(判斷條件) {}

案例1:把/etc/passwd中的每一行都重復打印3遍
[root@kubernetes ~]# awk -F: '{i=0;while(i<3){print $0;i++}}' /etc/passwd
           
       案例2:統計/etc/passwd中每個解析器的用戶數
[root@kubernetes ~]# awk -F: '{arr[$NF]++}END{for(i in arr){print i,arr[i]}}' /etc/passwd
         
       案例3:要求把/etc/passwd中第10行的中每一列都打印出來
operator:x:11:0:operator:/root:/sbin/nologin

operator
x
11
0

[root@kubernetes ~]# awk -F: 'NR==10{i=0;while(i<=NF){print $i;i++}}' /etc/passwd

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM