awk用法
原文地址: http://www.grymoire.com/Unix/Awk.html#uh-0
基本結構:
awk程序都是如此的一個基本結構:
pattern { action }
pattern指定,action是什麽時候執行的。AWK是以行為導向的。pattern就是指定了,在每一個行作為輸入的時候,進行一個測試。條件為真,就會采取行動。
沒人的pattern是匹配每一行。這就是blank或者是NULL pattern。除此之外的兩個模式是BEGIN和END。這兩個的意思是,在一個行作為輸入之前或之後進行指定的動作。
BEGIN { print "START" } { print } END { print"STOP" }
這個腳本沒有什麽用,但是作為修改之後,如下面:
#!/usr/bin/awk -f BEGIN { print "File\tOwner"} { print $8, "\t", $3} END { print " - DONE -" }
\t 指的是一個tab
"$8"和"$3"指的是第幾個變量(輸入行的域,列),和腳本差不多。
將上面的代碼保存為腳本FileOwner,並且設置可執行全縣,然後使用
ls -l | FileOwner
還可以直接寫成腳本:
#!/bin/bash -f # Linux users have to change $8 to $9 awk ‘\ BEGIN { print "File\tOwner" } { print $8, "\t", $3} END { print " - DONE -" } ‘
簡單用法:
如何使用變量定義列
#!/bin/bash column=1 awk ‘{print $‘$column‘}‘
默認值的用法:
#!/bin/bash # Linux users have to change $8 to $9 column=${3:-4} awk ‘{print $‘$column‘}‘
這節討論以下awk的不同的語法元素:
二元的操作符:
Operator | Type | Meaning |
---|---|---|
+ | Arithmetic | Addition |
- | Arithmetic | Subtraction |
* | Arithmetic | Multiplication |
/ | Arithmetic | Division |
% | Arithmetic | Modulo |
<space> | String | Concatenation |
使用範例如下:
Expression | Result |
---|---|
7+3 | 10 |
7-3 | 4 |
7*3 | 21 |
7/3 | 2.33333 |
7%3 | 1 |
7 3 | 73 |
awk沒有類型的概念。
"123"字符串,隨時回轉換為數字123. "123X" 會轉換為0(不同的awk有不同的定義。也有可能是123.)
單個操作符:
"+" and "-" operators 用於表示正負。
自增和自減操作符
"++" 和 "--" 行為和C語言一樣。
賦值操作符:
variable = arithmetic_expression
x=1+2*3 4; 的順序 等於 x = (1 + (2 * 3)) "4";
x=x+2; 等於 x+=2;
類似的操作符有:
Operator | Meaning |
---|---|
+= | Add result to variable |
-= | Subtract result from variable |
*= | Multiply variable by result |
/= | Divide variable by result |
%= | Apply modulo to variable |
條件表達式:
這些操作符可以用於if和while這些表達式當中:
Operator | Meaning |
---|---|
== | Is equal |
!= | Is not equal to |
> | Is greater than |
>= | Is greater than or equal to |
< | Is less than |
<= | Is less than or equal to |
正則表達式:
Operator | Meaning |
---|---|
~ | Matches |
!~ | Doesn‘t match |
使用例子:
word !~ /START/
lawrence_welk ~ /(one|two|three)/
and/or/not
"&&" and "||" and "!"
awk的命令
if ( conditional ) statement [ else statement ] while ( conditional ) statement for ( expression ; conditional ; expression ) statement for ( variable in array ) statement break continue { [ statement ] ...} variable=expression print [ expression-list ] [ > expression ] printf format [ , expression-list ] [ > expression ] next exit
用於打印平方(這是能夠在linux上bash和gawk運行的,和原文有區別)
#!/bin/awk -f BEGIN { # Print the squares from 1 to 10 the first way i=1; while (i <= 10) { printf "The square of " i " is " i*i "\n"; i = i+1; } # do it again, using more concise code for (i=1; i <= 10; i++) { printf "The square of " i " is " i*i "\n"; } # now end exit; }
還有另外一個嘗試的版本:
#!/bin/awk -f BEGIN { # Print the squares from 1 to 10 the first way i=1; while (i <= 10) { print "The square of ", i ," is ", i*i, "\n"; i = i+1; } # do it again, using more concise code for (i=1; i <= 10; i++) { printf "The square of " i " is " i*i "\n"; } # now end exit; }
在這裏,第一個,我註意到 變量i 使用的時候, 就只需要打出i就可以了。
第二個,print 可以使用逗號(,)來進行連接, printf使用空格( )來進行連接字符串。
第二個接受一個參數,然後返回平方:
#!/bin/awk -f BEGIN { print "type a number"; } { print "The square of ", $1, " is ", $1*$1; print "type another number"; } END { print "Done" }
這個程序匯呈現循環的方式來進行的,問了一個又一個。
結果
type a number 12 The square of 12 is 144 type another number 22 The square of 22 is 484 type another number 33 The square of 33 is 1089 type another number
可以這樣使用:
$ echo 1 | ./awk.example.1.bash type a number The square of 1 is 1 type another number
下面是這樣一個程序, 他清點所有的行數,並且把第一列的行的數加起來,並且計算平均值
$ wc -c * 414 awk.example.1.bash 304 awk.example.1.bash~ 94 FileOwner 0 FIleOwner~ 825 Makefile 1637 total
然後
wc -c * | ./awk.example.1.bash 6 lines read total is 3274 average is 545.667
awk的內置變量:
有兩種變量,第一個是用戶定義的,第二個是位置變量。
位置變量不是一個特殊的變量,而是由美元符號($)所開頭的一個變量。
因此:
#!/bin/awk -f
BEGIN {
print $1; # 輸出第一個位置變量
X=1;
print $X; # 同樣也是輸出第一個位置變量
print X # 輸出變量X
}
有一個特殊的變量: $0,所指的是輸出所有awk所讀入的整行
如果你輸入了8個域,在一行,就等於
print $0; print $1, $2, $3, $4, $5, $6, $7, $8
要註意,這個不要在BEGIN上面用,是沒有用的哦
#!/bin/awk -f BEGIN { print $0; # 完全每輸出 } { print $0; }
你也可以修改這個域的值為空,如下
$ wc -c * 40 awk.example.1.bash 304 awk.example.1.bash~ 94 FileOwner 0 FIleOwner~ 825 Makefile 1263 total #!/bin/awk -f { $2=""; print; } $ wc -c * | ./awk.example.1.bash 77 304 94 0 825 1300
和以下對比:
#!/bin/awk -f { print $1; } wc -c * | ./awk.example.1.bash 32 304 94 0 825 1255 [[email protected] 2]$
結果是一樣的,但是不完全一樣。我也不知道有什麽不一樣阿。
FS 輸入的分割符
awk的-F可以用來作為分割符:
awk -F: ‘{if ($2 == "") print $1 ": no password!"}‘ < /etc/passwd
這個把一行根據:來進行分域。
同樣的,可以使用FS作為分割符
#!/bin/awk -f BEGIN { FS=":"; } { if ( $2 == "" ) { print $1 ": no password!"; } } # 使用方法 $ ./awk.example.1.bash < /etc/passwd
這時候再使用-F選項是沒有用的。因為直接調用了"#!/bin/awk -f"
還有一個優點就是,可以i設置多於一個的分割符。
# 文本 ONE 1 I TWO 2 II #START THREE:3:III FOUR:4:IV FIVE:5:V #STOP SIX 6 VI SEVEN 7 VII # 處理的腳本 #!/bin/awk -f { if ($1 == "#START") { FS=":"; } else if ($1 == "#STOP") { FS=" "; } else { #print the Roman number in column 3 print $3 } }
以下另外一個腳本,輸出比較奇怪
# 文本 # One Two:Three:4 Five #!/bin/awk -f { print $2 FS=":" print $2 } # 輸出: Two:Three:4 Two:Three:4 #!/bin/awk -f { FS=":" print $2 } # 輸出 Three
原因就是: 在讀入輸入之前改變FS,是有效的;在讀入之後,就不會再有效了。默認FS是空格
但是能使用這個方法來進行動態定義:
#!/bin/awk -f { if ( $0 ~ /:/ ) { FS=":"; $0=$0 } else { FS=" "; $0=$0 } #print the third field, whatever format print $1 } # 輸出 One Two
OFS 輸出域的分割符
#!/bin/awk -f { # 只會輸出第一個域,這是因為,空格連接的$2和$3,然後輸出的時候沒有一個空格 print $2 $3 # 輸出兩個域,第二個awk會在,號中放入一個空格(默認的OFS就是空格) print $2, $3 }
在輸出的時候取消密碼,可以這麽做
#!/bin/awk -f BEGIN { FS=":"; OFS=":"; } { $2=""; print }
awk用法