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中是可以用邏輯符号判斷的,比如 ‘==’ 就是等于,也可以了解為 ‘精确比對’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和數字比較時,若把比較的數字用雙引号引起來後,那麼awk不會認為是數字,而認為是字元,不加雙引号則認為是數字。
示例,雙引号括起來認為是字元;加單引号和不加則認為是數字;
<code>[root@yonglinux ~]</code><code># awk -F: '$3>"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>500' passwd | sort -t: -k 3 -n </code>
<code>[root@yonglinux ~]</code><code># awk -F: '$3>'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>"5" && $3<"7"' passwd </code>
示例,加單引号之後為數字比較;
<code>[root@yong ~]</code><code># awk -F: '$3>'5' && $3<'7' {print }' passwd</code>
另外還可以使用 && “并且”和 || “或者” 的意思。
示例,列印第3段大于第4段,并且第7段為/bin/bash的行;
<code>[root@yonglinux ~]</code><code># awk -F: '$3>$4 && $7=="/bin/bash"' passwd </code>
示例,列印第3段小于第4段,或者第7段為/bin/bash的行;
<code>[root@yonglinux ~]</code><code># awk -F: '$3<$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,如需轉載請自行聯系原作者