1. 程式人生 > >awk用法

awk用法

-a 默認值 均值 col opera tar lan 完全 ray

原文地址: 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的不同的語法元素:

二元的操作符:

OperatorTypeMeaning
+ Arithmetic Addition
- Arithmetic Subtraction
* Arithmetic Multiplication
/ Arithmetic Division
% Arithmetic Modulo
<space> String Concatenation

使用範例如下:

ExpressionResult
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;

類似的操作符有:

OperatorMeaning
+= Add result to variable
-= Subtract result from variable
*= Multiply variable by result
/= Divide variable by result
%= Apply modulo to variable

條件表達式:

這些操作符可以用於if和while這些表達式當中:

OperatorMeaning
== Is equal
!= Is not equal to
> Is greater than
>= Is greater than or equal to
< Is less than
<= Is less than or equal to

正則表達式:

OperatorMeaning
~ 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用法