shell 腳本- awk工具

[toc]bash


# 正則三劍客- awkpost

## awk與sed、grep的不一樣之處是支持分段處理;測試

### 創建測試環境,建立一個awk目錄並copy passwd到 awk目錄下。編碼

```
[root@localhost ~]# cd awk
[root@localhost awk]#  cp /etc/passwd awk/test.txt.net

[root@localhost awk]# awk -F ':' '{print $1}' test.txt
```
### 1. -F是制定分隔符,print爲打印動做,用來打印某個字段,$1爲第1個字段,$2爲第2個字段,以此類推,但$0比較特殊,它表示整行:排序

```字符串

# awk -F ‘:’ ‘{print $1}’ passwd               -F:指定分隔符 //打印passwd的第一段
$1:第一段 ,$2:第二段,$0:整行
# awk -F ‘:’ ‘{print $0}’ passwd              -F:指定分隔符 //打印passwd的整行所有內容
若是不指定分隔符,默認是空格
# awk -F ‘:’ ‘{print $1,$3,$4}’ passwd                //同時打印第1,3,4段
#awk -F ‘:’ ‘{print $1「#」$3「#」$4}’ passwd          //指定打印結果以某個字符分割
```
![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/AlAe6d2iEd.png?imageslim)
![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/I46Gj0Hmeb.png?imageslim)get

### 2. -F 後面緊跟單引號,單引號內製定分隔符,print的動做要用{}括起來,能夠自定義內容,但內容要加雙引號。數學

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/JbfFbaLfLC.png?imageslim)for循環

### 3.匹配字符或者字符串
示例命令:

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180520/keFGK91egc.png?imageslim)

```
[root@localhost awk]# awk '/oo/' test.txt
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
setroubleshoot:x:991:986::/var/lib/setroubleshoot:/sbin/nologin
```
這和sed的用法類似,實現grep功能,沒有顏色顯示,這裏還能夠匹配某一段,這裏~就是匹配的意思

```
[root@localhost awk]# awk -F ':' '$1 ~/oo/' test.txt
root:x:0:0:root:/root:/bin/bash
setroubleshoot:x:991:986::/var/lib/setroubleshoot:/sbin/nologin
```
4.awk支持特殊字符+等,且沒必要和grep那樣+E,sed +r
![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/LjBHjA61C0.png?imageslim)

5. awk支持多個表達式,下例中awk匹配完root,再匹配test,它還能夠只打印所匹配的段。
```
[root@localhost awk]# awk -F ':' '/root/ {print $1,$2} /test/ {print $1,$3}' test.txt
root x
operator x
test 1002
```
### 6. 條件操做符

* awk中是能夠用邏輯符號判斷的,好比 ‘==’ 就是等於,也能夠理解爲 ‘精確匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和數字比較時,若把比較的數字用雙引號引發來後,那麼awk不會認爲是數字,而認爲是字符,不加雙引號則認爲是數字。
示例:

```
[root@localhost awk]# awk -F ':' '$3>=1000 {print $0}' test.txt
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
xavi:x:1000:1000:xavi,xavi's office,62580558,62589906:/home/xavi:/bin/bash
xavidsf:x:1001:1001:xavi:/home/xavidsf:/bin/bash
test:x:1002:1002::/home/test:/bin/bash
Ding:x:1003:1003::/home/Ding:/bin/bash
```

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/J3bAaEm6FJ.png?imageslim)

* 這裏1000和「1000」的區別,「1000」是字符串,按照ASCII碼來比較大小,這就和sort排序是同樣的了

#### ASCII比較大小

```
ASCII比較大小的時候,是比較兩個數中的第一個字符 
1)經常使用字符有128個,編碼從0到127。 
2)控制字符:0~3一、127,共33個,不可顯示; 
3)普通字符:95個,包括10個阿拉伯數字、52個英文大小寫字母、33個運算符。 
4)每一個字符佔一個字節,7位,最高位爲0。 
常見ASCII碼的大小規則,0-9<A-Z<a-z: 
1)數字比字母要小。如 「7」<「F」 
2)數字0比數字9要小,並按0到9順序遞增。如 「3」<「8」 
3)字母A比字母Z要小,並按A到Z順序遞增。如「A」<「Z」 
4)同個字母的大寫字母比小寫字母要小32。如「A」<「a」 
記住幾個常見字母的ASCII碼大小: 
「A」爲65;「a」爲97;「0」爲48;
```

* != 爲不匹配,除了針對某一個段的字符進行邏輯比較外,還能夠兩個段之間進行邏輯比較:

```
[root@localhost awk]# awk -F ':' '$7!="/sbin/nologin" {print $0}' test.txt
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
xavi:x:1000:1000:xavi,xavi's office,62580558,62589906:/home/xavi:/bin/bash
xavidsf:x:1001:1001:xavi:/home/xavidsf:/bin/bash
test:x:1002:1002::/home/test:/bin/bash
Ding:x:1003:1003::/home/Ding:/bin/bash
```
* $3<$4,$3==$4等進行比較

```
[root@localhost awk]# awk -F ':' '$3<$4' test.txt
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
```
* 還可使用&&和||,表示而且和或者,以及~匹配。

```
[root@localhost awk]# awk -F ':' '$3>"5"&& $4<"7"' test.txt
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
```

```
[root@localhost awk]# awk -F ':' '$3>1000 || $7~"/bash"' test.txt
root:x:0:0:root:/root:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
xavi:x:1000:1000:xavi,xavi's office,62580558,62589906:/home/xavi:/bin/bash
xavidsf:x:1001:1001:xavi:/home/xavidsf:/bin/bash
test:x:1002:1002::/home/test:/bin/bash
Ding:x:1003:1003::/home/Ding:/bin/bash
[root@localhost awk]# awk -F ':' '$3>1000 || $7 ~/bash/' test.txt
root:x:0:0:root:/root:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
xavi:x:1000:1000:xavi,xavi's office,62580558,62589906:/home/xavi:/bin/bash
xavidsf:x:1001:1001:xavi:/home/xavidsf:/bin/bash
test:x:1002:1002::/home/test:/bin/bash
Ding:x:1003:1003::/home/Ding:/bin/bash 
```
### 7 awk的內置變量

* awk經常使用的變量有:OSF、NF和NR。OFS與-F選項功能相似,用來定義分隔符,可是它是用在輸出時候定義。NF表示用分隔符分隔後一共多少行,NR表示行號。

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/miJCb1Aa16.png?imageslim)

* 嵌套if語句

```
[root@localhost awk]# awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' /etc/passwd
nfsnobody#x#65534#65534
xavidsf#x#1001#1001
test#x#1002#1002
Ding#x#1003#1003
```
* NR表示行號,NF表示多少段
- [ ] #awk -F ':' '{print NR":"$0}' test.txt
- [ ] awk -F ':' '{print NF}' test.txt

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/HFfIjKF7Gm.png?imageslim)
![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/8fEm04H9K3.png?imageslim)

* NR還能夠做爲判斷條件,顯示10行;

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/k24B6hA4jJ.png?imageslim)

* NR配合段匹配一個使用,NR也是同理使用

```
[root@localhost awk]# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' test.txt
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
```
### 8 awk 的數學運算

* =與==的區別,一個是賦值,即更改某些段的數值或字符,==是一個是判斷

![mark](http://p0weeraap.bkt.clouddn.com/xavi2017/180117/0DAc21FjeD.png?imageslim)
* 沒有冒號,能夠在OFS中定義

```
[root@localhost awk]# head -n 3 test.txt |awk -F ':' '{OFS=":"} $1="root"'
root:x:0:0:root:/root:/bin/bash
root:x:1:1:bin:/bin:/sbin/nologin
root:x:2:2:daemon:/sbin:/sbin/nologin
```
* awk對各段的值進行數學運算,示例以下:

``` [root@localhost awk]# head -n 3 test.txt |awk -F ':' '{$7=$3+$4;print $0}' root x 0 0 root /root 0 bin x 1 1 bin /bin 2 daemon x 2 2 daemon /sbin 4 ``` * awk計算某個段的總和,這裏的END要注意一下,表示全部的行都已經執行,這是awk特有的語法,其實awk連同sed均可以寫成一個腳本文件,並且有他們特有的語法,在awk中使用if判斷、for循環都是能夠的。 ``` [root@localhost awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd 82235 ```  

相關文章
相關標籤/搜索