Linux之awk使用


awk介紹

awk可以認為是一門語言,非常強大。
awk工作流程是這樣的:先執行BEGIN,然后讀取文件,讀入換行符分割的一條記錄,然后將記錄按指定的域分隔符划分域,填充域,隨后開始執行模式所對應的動作action。接着開始讀入第二條記錄······直到所有的記錄都讀完,最后執行END操作。

調用方式

三種調用方式
awk '{pattern + action}' {filenames}

+ 命令行方式:
```awk [-F field-separator] 'commands' input-file(s)```
其中,commands 是真正awk命令,[-F域分隔符]是可選的。 input-file(s) 是待處理的文件。
在awk中,文件的每一行中,由域分隔符分開的每一項稱為一個域。通常,在不指名-F域分隔符的情況下,默認的域分隔符是空格。

+ shell腳本方式
將所有的awk命令插入一個文件,並使awk程序可執行,然后awk命令解釋器作為腳本的首行,一遍通過鍵入腳本名稱來調用。
相當於shell腳本首行的:```#!/bin/sh``` 可以換成:```#!/bin/awk```

+ 將所有的awk命令插入一個單獨文件,然后調用:```awk -f awk-script-file input-file(s)```; 其中,-f選項加載awk-script-file中的awk腳本,input-file(s)跟上面的是一樣的。

內置變量

+ ARGC: 命令行參數個數
+ ARGV: 命令行參數排列
+ ENVIRON: 支持隊列中系統環境變量的使用
+ FILENAMEawk: 瀏覽的文件名
+ FNR: 瀏覽文件的記錄數
+ FS: 設置輸入域分隔符,等價於命令行-F選項
+ NF: 瀏覽記錄的域個數
+ NR: 已讀的記錄數
+ OFS: 輸出域分隔符
+ ORS: 輸出記錄分隔符
+ RS: 控制記錄分隔符
+ $0變量是指整條記錄

流程控制

+ awk中的條件語句是從C語言中借鑒來的
+ 循環語句同樣借鑒於C語言,支持while、do/while、for、break、continue,這些關鍵字的語義和C語言中的語義完全相同。

#### 其他
+ print函數的參數可以是變量、數值或者字符串。字符串必須用雙引號引用,參數用逗號分隔。如果沒有逗號,參數就串聯在一起而無法區分。這里,逗號的作用與輸出文件的分隔符的作用是一樣的,只是后者是空格而已。
```print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0```
+ printf函數,其用法和c語言中printf基本相似,可以格式化字符串,輸出復雜時,printf更加好用,代碼更易懂。
```printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)```

實例

##### 1-BEGIN和END的使用
```cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'```

##### 2-pattern使用模式-搜索/etc/passwd有root關鍵字的所有行
```awk -F: '/root/' /etc/passwd```

+ 這種是pattern的使用示例,匹配了pattern(這里是root)的行才會執行action(沒有指定action,默認輸出每行的內容)。pattern是支持正則的。

##### 3-顯示文件file的當前記錄號、域數和每一行的第一個和最后一個域。
```awk '{print NR,NF,$1,$NF,}' file```

##### 4-顯示第4個域滿足條件的行
```df | awk '$4>1000000 '```

##### 5-顯示文件中第一個域匹配101的行
```awk '$1 ~ /101/ {print $1}' file```

##### -下載指定網頁的所有img選項
```
for info in $(curl -k -s http://www.eztang.cn/shejituandui/120.html \
|grep img |grep uploads \
|awk -F"src=" '{print $2}' |awk -F "\"|'" '{print $2}'
);
do
filename=$(echo -n ${info} |awk -F/ '{print $NF}')
curl -k -s http://www.eztang.cn${info} > $filename
done
```

計算

```
cat redis_redis8389.dump.rdb.201712261040.csv.log |grep COPY |grep -v CONTEXT |awk -F' ' '{ sum += $2 } END { print sum }'
ls s07_s06_s05_s04_s03_s02_* |xargs cat > err.log
awk -F',' '{if(NF>=4)sum += $(NF-3)} END { print sum }' err.log

cat xxx.log |head |awk -F" " '{print $8}' |awk -F',' 'BEGIN{
RS="\n+"
}
{
sum+=$0
}
NR==1 {
max=$1;min=$1
next
}
$1>max {
max=$1
}
$1<min {
min=$1
}
END{
printf "max number is:%s\n",max
printf "min number is:%s\n",min
printf "sum number is:%s\n",sum
printf "average is:%.2f\n",sum/NR
}'
```

打印定義內容

cat 1.log |awk -F' ' '{print NR" "$1 $2" nan nan"}'

#### 單引號
awk '{print "'\''"}'

#### 分類統計
```
$ cat datafile
姓名 類型 金額
張三 1 27.43
李四 2 33.44
張三 2 55.55
丁六 1 66.66
趙七 1 77.77
$ cat datafile |awk -F' ' '{types[$2]+=$3;count[$2]++}END{for(i in types) printf"類型%s 共%d行 合計 %f\n",i,count[i],types[i]}'
類型類型 共1行 合計 0.000000
類型1 共3行 合計 171.860000
類型2 共2行 合計 88.990000
```


免責聲明!

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



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