天天看點

linux正規表達式awk講解

awk和sed一樣是流式編輯器,它也是針對文檔中的行來操作的,一行一行的去執行。awk比sed更加強大,它能做到sed能做到的,同樣也能做到sed不能做到的。awk常用來分段;

awk不用加任何參數就可以實作 + ? * .  | 這些特殊符号;

1、截取文檔中的某個段

1

2

3

4

5

6

7

8

9

<code>[root@yonglinux ~]</code><code># head -n2 passwd |awk -F: '{print $1}'</code>

<code>root</code>

<code>bin</code>

<code>[root@yonglinux ~]</code><code># head -n2 passwd |awk -F: '{print $0}'</code>

<code>root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code>

<code>bin:x:1:1:bin:</code><code>/bin</code><code>:</code><code>/sbin/nologin</code>

<code>[root@yonglinux ~]</code><code># head -n2 passwd |awk -F: '{print $1,$3,$7}'</code>

<code>root 0 </code><code>/bin/bash</code>

<code>bin 1 </code><code>/sbin/nologin</code>

-F 選項的作用是指定分隔符,如果不加-F指定,則以空格或者tab為分隔符。 Print為列印的動作,用來列印出某個字段。$1為第一個字段,$2為第二個字段,依次類推,有一個特殊的那就是$0,它表示整行。

{ }内可以列印多個字段$1,$3,$7 列印第1、3、7段,中間用逗号隔開;

列印分段預設分隔符為空格,可以自定義分隔符,分隔符需要用雙引号括起來;也可以OFS定義輸出分隔符;

10

11

12

13

14

15

16

17

18

<code>[root@localhost ~]</code><code># awk -F: '{print $3,$4}' 1.txt |head -5</code>

<code>0 0</code>

<code>1 1</code>

<code>2 2</code>

<code>3 4</code>

<code>4 7</code>

<code>[root@localhost ~]</code><code># awk -F: '{print $3":"$4}' 1.txt |head -5</code>

<code>0:0</code>

<code>1:1</code>

<code>2:2</code>

<code>3:4</code>

<code>4:7</code>

<code>[root@localhost ~]</code><code># awk -F: 'OFS="#"{print $3,$4}' 1.txt |head -5</code>

<code>0</code><code>#0</code>

<code>1</code><code>#1</code>

<code>2</code><code>#2</code>

<code>3</code><code>#4</code>

<code>4</code><code>#7</code>

<code>[root@yonglinux ~]</code><code># head -n2 passwd |awk -F: '{print $1"#""@"$3"#"$7}'</code>

<code>root</code><code>#@0#/bin/bash</code>

<code>bin</code><code>#@1#/sbin/nologin</code>

注意awk的格式,-F後緊跟單引号,然後裡面為分隔符,print的動作要用 { } 括起來,否則會報錯。print還可以列印自定義的内容,但是自定義的内容要用“”雙引号括起來。

2、比對字元或字元串

<code>[root@yonglinux ~]</code><code># awk -F: '$1~/me/' passwd </code>

<code>games:x:12:100:games:</code><code>/usr/games</code><code>:</code><code>/sbin/nologin</code>

<code>[root@yonglinux ~]</code><code># awk -F: '$1~/user/' passwd </code>

<code>user1:x:600:501::</code><code>/home/user1</code><code>:</code><code>/bin/bash</code>

可以讓某個段去比對,~ 表示比對的意思,以冒号分隔第一字段然後比對//裡的關鍵字;

<code>[root@yonglinux ~]</code><code># awk -F: '/root/ {print $1,$3} /user/ {print $1,$3}' passwd </code>

<code>root 0</code>

<code>operator 11</code>

<code>ftp</code> <code>14</code>

<code>saslauth 499</code>

<code>user1 600</code>

awk還可以多次比對,如上例全文比對包含root關鍵詞的行,再比對包含user的行,列印所比對的第1、3段。

3、條件操作符

判斷第3個字段為0的

<code>[root@yonglinux ~]</code><code># awk -F: '$3=="0"' passwd </code>

<code>[root@yonglinux ~]</code><code># awk -F: '$3==10' passwd </code>

<code>uucp:x:10:14:uucp:</code><code>/var/spool/uucp</code><code>:</code><code>/sbin/nologin</code>

判斷第3個字段為10的并且列印該行的第7字段;

<code>[root@yonglinux ~]</code><code># awk -F: '$3==10 {print $7}' passwd </code>

<code>/sbin/nologin</code>

<code>[root@yonglinux ~]</code><code># awk -F: '$3=="600"' passwd </code>

awk中是可以用邏輯符号判斷的,比如 ‘==’ 就是等于,也可以了解為 ‘精确比對’ 另外也有 &gt;, ‘&gt;=, ‘&lt;, ‘&lt;=, ‘!= 等等,值得注意的是,在和數字比較時,若把比較的數字用雙引号引起來後,那麼awk不會認為是數字,而認為是字元,不加雙引号則認為是數字。

示例,雙引号括起來認為是字元;加單引号和不加則認為是數字;

<code>[root@yonglinux ~]</code><code># awk -F: '$3&gt;"500"' passwd | sort -t: -k 3 -n </code>

<code>shutdown</code><code>:x:6:0:</code><code>shutdown</code><code>:</code><code>/sbin</code><code>:</code><code>/sbin/shutdown</code>

<code>halt:x:7:0:halt:</code><code>/sbin</code><code>:</code><code>/sbin/halt</code>

<code>mail:x:8:12:mail:</code><code>/var/spool/mail</code><code>:</code><code>/sbin/nologin</code>

<code>vcsa:x:69:69:virtual console memory owner:</code><code>/dev</code><code>:</code><code>/sbin/nologin</code>

<code>sshd:x:74:74:privilege-separated </code><code>ssh</code><code>:</code><code>/var/empty/sshd</code><code>:</code><code>/sbin/nologin</code>

<code>dbus:x:81:81:system message bus:/:</code><code>/sbin/nologin</code>

<code>postfix:x:89:89::</code><code>/var/spool/postfix</code><code>:</code><code>/sbin/nologin</code>

<code>nobody:x:99:99:nobody:/:</code><code>/sbin/nologin</code>

<code>[root@yonglinux ~]</code><code># awk -F: '$3&gt;500' passwd | sort -t: -k 3 -n </code>

<code>[root@yonglinux ~]</code><code># awk -F: '$3&gt;'500'' passwd | sort -t: -k 3 -n </code>

!= 為不比對,第7字段不等于/sbin/nologin的行,需要用雙引号括起來。

<code>[root@yonglinux ~]</code><code># awk -F: '$7!="/sbin/nologin"' passwd </code>

<code>sync</code><code>:x:5:0:</code><code>sync</code><code>:</code><code>/sbin</code><code>:</code><code>/bin/sync</code>

<code>mysql:x:27:27:MySQL Server:</code><code>/var/lib/mysql</code><code>:</code><code>/bin/bash</code>

除了針對某一個段的字元進行邏輯比較外,還可以兩個段之間進行邏輯比較。

示例,加雙引号之後把數字當字元看;

<code>[root@yonglinux ~]</code><code># awk -F: '$3&gt;"5" &amp;&amp; $3&lt;"7"' passwd </code>

示例,加單引号之後為數字比較;

<code>[root@yong ~]</code><code># awk -F: '$3&gt;'5' &amp;&amp; $3&lt;'7' {print }' passwd</code>

另外還可以使用 &amp;&amp; “并且”和  || “或者” 的意思。

示例,列印第3段大于第4段,并且第7段為/bin/bash的行;

<code>[root@yonglinux ~]</code><code># awk -F: '$3&gt;$4 &amp;&amp; $7=="/bin/bash"' passwd </code>

示例,列印第3段小于第4段,或者第7段為/bin/bash的行;

<code>[root@yonglinux ~]</code><code># awk -F: '$3&lt;$4 || $7=="/bin/bash"' passwd </code>

<code>adm:x:3:4:adm:</code><code>/var/adm</code><code>:</code><code>/sbin/nologin</code>

<code>lp:x:4:7:lp:</code><code>/var/spool/lpd</code><code>:</code><code>/sbin/nologin</code>

<code>gopher:x:13:30:gopher:</code><code>/var/gopher</code><code>:</code><code>/sbin/nologin</code>

<code>ftp</code><code>:x:14:50:</code><code>ftp</code> <code>user:</code><code>/var/ftp</code><code>:</code><code>/sbin/nologin</code>

<code>mysql:x:27:27:mysql server:</code><code>/var/lib/mysql</code><code>:</code><code>/bin/bash</code>

4、awk的内置變量

awk常用的變量有:

NF :用分隔符分隔後一共有多少段

NR :行數

{print NR":"NF}    列出行号,以冒号分隔,列出共有多少段;

19

20

21

22

23

24

<code>[root@yonglinux ~]</code><code># head -5 passwd |awk -F: '{print NR":"NF}'</code>

<code>1:7</code>

<code>2:7</code>

<code>3:7</code>

<code>5:7</code>

<code>[root@yonglinux ~]</code><code># head -5 passwd |awk -F: '{print NF}'</code>

<code>7</code>

<code>[root@yonglinux ~]</code><code># head -5 passwd |awk -F: '{print NR}'</code>

<code>1</code>

<code>2</code>

<code>3</code>

<code>4</code>

<code>5</code>

<code>[root@yonglinux ~]</code><code># head -5 passwd |awk -F: '{print $NF}'</code>

<code>/bin/bash</code>

<code>[root@yonglinux ~]</code><code># awk -F: '{(tot=tot+$3)};END {print tot};' passwd </code>

<code>1720</code>

這裡的END要注意一下,表示所有的行都已經執行,這是awk特有的文法,其實awk連同sed都可以寫成一個腳本檔案,而且有他們特有的文法,在awk中使用if判斷、for循環都是可以的。

示例,if判斷,如第一段的值為root,列印整行;

<code>[root@yonglinux ~]</code><code># awk -F: '{if ($1=="root") print $0}' passwd </code>

示例,for循環,定義sum變量,i值為第3段的值;求第3段的和;

<code>[root@yonglinux ~]</code><code># sum=0;for i in `awk -F: '{print $3}' passwd`;do sum=$[($sum+$i)];done;echo $sum</code>

本文轉自 模範生 51CTO部落格,原文連結:http://blog.51cto.com/mofansheng/1633022,如需轉載請自行聯系原作者

繼續閱讀