awkawk入門

備註

AWK的名字來自其創作者Alfred V. Aho,Peter J. Weinberger和
Brian W. Kernighan。

資源

版本

名稱初始版本發布日期
POSIX awk 1992年 IEEE Std 1003.1,2013 Edition 2013年4月19日
一個真Awk或nawk或BWK awk 198X - 二○一二年十二月二十〇日
GNU awk或gawk 1986年 4.1.3 2015年5月19日

你好,世界

Hello world示例非常簡單:

awk 'BEGIN {print "Hello world"}'

最基本的awk程序由一個真值(通常為1 )組成,並使awk回顯其輸入:

$ date | awk '1'
Mon Jul 25 11:12:05 CEST 2016

既然“你好世界”也是一個真正的價值,你也可以說:

$ date | awk '"hello world"'
Mon Jul 25 11:12:05 CEST 2016

但是,如果你寫作,你的意圖會變得更加清晰

$ date | awk '{print}'
Mon Jul 25 11:12:05 CEST 2016

代替。

如何運行AWK程序

如果程序很短,可以將它包含在運行awk的命令中:

awk -F: '{print $1, $2}' /etc/passwd

在這個例子中,使用命令行開關-F:我們建議awk使用:作為輸入字段分隔符。是一樣的

awk 'BEGIN{FS=":"}{print $1,$2}' file

或者,我們可以將整個awk代碼保存在awk文件中並像這樣調用這個awk程序:

awk -f 'program.awk' input-file1 input-file2 ...

program.awk可以是任何多行程序,即:

# file print_fields.awk
BEGIN {print "this is a header"; FS=":"}
{print $1, $2}
END {print "that was it"}

然後運行它:

awk -f print_fields.awk /etc/passwd   #-f advises awk which program file to load

或者更一般地說:

awk -f program-file input-file1 input-file2 ...

將程序放在一個單獨的文件中的優點是你可以編寫具有正確標識的程序來理解,你可以用#等包含註釋

AWK通過例子

AWK是字符串操作語言,主要用於UNIX系統。 AWK背後的想法是創建一種在處理文件時使用的通用語言,這種語言並不太複雜,無法理解。

AWK還有其他一些變體,但主要概念是相同的,只是附加功能。這些其他變體是NAWK和GAWK。 GAWK包含兩者的所有功能,如果您願意,NAWK比AWK高出一步。

想到AWK最簡單的方法是考慮它有兩個主要部分。模式和行動。

可能是AWK最基本的例子:(參見:Hello World)

BEGIN {print "START"}
      {print        }
END   {print "STOP" }

這裡,關鍵字BEGINEND是模式,而動作在{}內。這個例子沒用,但實際上只需要做一些小改動就可以使它成為一個有用的函數。

BEGIN {print "File\tAuthor"}
      {print $8, "\t", $3}
END {print " - DONE - "}

這裡, \t表示製表符,用於平滑輸出行邊界。 $ 8和$ 3類似於Shell Scripts的使用,但它不使用第3和第8個參數,而是使用輸入行的第3和第8列。

因此,此示例將打印:文件作者位於頂行,而第二行則處理文件路徑。 $ 8是文件的名稱,$ 3是所有者(當查看目錄路徑時,這將更加清晰)。最後,底線將打印,如您所料 - 完成 -

以上示例的信用轉到http://www.grymoire.com/Unix/Awk.html

參考文件

來自Greg Goebel的coins.txt

gold     1    1986  USA                 American Eagle
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona
silver  10    1981  USA                 ingot
gold     1    1984  Switzerland         ingot
gold     1    1979  RSA                 Krugerrand
gold     0.5  1981  RSA                 Krugerrand
gold     0.1  1986  PRC                 Panda
silver   1    1986  USA                 Liberty dollar
gold     0.25 1986  USA                 Liberty 5-dollar piece
silver   0.5  1986  USA                 Liberty 50-cent piece
silver   1    1987  USA                 Constitution dollar
gold     0.25 1987  USA                 Constitution 5-dollar piece
gold     1    1988  Canada              Maple Leaf

最小的理論

一般awk單行:

awk <awk program> <file>

要么:

<shell-command> | awk <awk program> 

<shell-command><file>作為awk輸入進行尋址。

<awk program>是此模板後面的代碼(單個,不是雙引號):

'BEGIN   {<init actions>};
 <cond1> {<program actions>};
 <cond2> {<program actions>};
 ...
 END  {<final actions>}'

哪裡:

  • <condX>條件通常是正則表達式/re/ ,與awk輸入行匹配;
  • <* actions>語句序列,類似於shell命令,配有類似C的結構。

``按照以下規則處理:
  1. BEGIN ...END ...是可選的,在處理awk輸入行之前或之後執行。
  2. 對於awk輸入中的每一行,如果condition <condN>為meat,則執行相關的<program actions>塊。
  3. {<program actions>}默認為{print $0}

條件可以與標準邏輯運算符組合:

    /gold/ || /USA/ && !/1986/

其中&&優先於|| ;

print聲明print item1 item2語句在STDOUT上打印項目。
項可以是變量( X$0 ),字符串(“hello”)或數字。
item1, item2OFS變量的值進行整理;
item1 item2 只是justapoxed !使用item1 " " item2表示空格或printf表示更多功能。

變量不需要$ ,即: print myVar;
以下特殊變量在awk中內置:

  • FS :充當字段分隔符以在字段中拆分awk輸入行。我可以是單個角色, FS="c" ;空字符串, FS="" (然後每個單獨的字符成為一個單獨的字段);一個沒有斜杠的正則表達式, FS="re" ; FS=" "代表空格和製表符的運行,是默認值。
  • NF :要讀取的字段數;
  • $1 $2 ,......:第1場,第2場。等當前輸入行,
  • $0 :當前輸入線;
  • NR :當前放線號。
  • OFS :字符串在打印時整理字段。
  • ORS :輸出記錄分隔符,默認為換行符。
  • RS :輸入行(記錄)分隔符。默認為換行符。設為FS
  • IGNORECASE :當正則表達式時影響FS和RS;

例子

通過regexp gold過濾行併計算它們:

# awk 'BEGIN {print "Coins"} /gold/{i++; print $0}  END {print i " lines out of " NR}' coins.txt
Coins
gold     1    1986  USA                 American Eagle      
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona 
gold     1    1984  Switzerland         ingot 
gold     1    1979  RSA                 Krugerrand 
gold     0.5  1981  RSA                 Krugerrand 
gold     0.1  1986  PRC                 Panda                       
gold     0.25 1986  USA                 Liberty 5-dollar piece
gold     0.25 1987  USA                 Constitution 5-dollar piece
gold     1    1988  Canada              Maple Leaf
9 lines out of 13

默認print $0基於內部awk變量NR動作和條件:

# awk 'BEGIN {print "First 3 coins"} NR<4' coins.txt
First 3 coins                                                  
gold     1    1986  USA                 American Eagle         
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona 
silver  10    1981  USA                 ingot
使用C風格的“printf”格式化:
# awk '{printf ("%s \t %3.2f\n", $1, $2)}' coins.txt
gold     1.00                                      
gold     1.00                                      
silver   10.00                                     
gold     1.00                                      
gold     1.00                                      
gold     0.50                                      
gold     0.10                                      
silver   1.00                                      
gold     0.25                                      
silver   0.50                                      
silver   1.00                                      
gold     0.25                                      
gold     1.00

條件例子

awk 'NR % 6'            # prints all lines except those divisible by 6
awk 'NR > 5'            # prints from line 6 onwards (like tail -n +6, or sed '1,5d')
awk '$2 == "foo"'       # prints lines where the second field is "foo"
awk '$2 ~ /re/'         # prints lines where the 2nd field mateches the regex /re/
awk 'NF >= 6'           # prints lines with 6 or more fields
awk '/foo/ && !/bar/'   # prints lines that match /foo/ but not /bar/
awk '/foo/ || /bar/'    # prints lines that match /foo/ or /bar/ (like grep -e 'foo' -e 'bar')
awk '/foo/,/bar/'       # prints from line matching /foo/ to line matching /bar/, inclusive
awk 'NF'                # prints only nonempty lines (or: removes empty lines, where NF==0)
awk 'NF--'              # removes last field and prints the line

通過添加動作{...}可以打印特定字段,而不是整行,例如:

awk '$2 ~ /re/{print $3 " " $4}'

打印第二個字段匹配正則表達式/ re /的第三和第四個字段。

一些字符串函數

substr()函數:

# awk '{print substr($3,3) " " substr($4,1,3)}' 
86 USA                                            
08 Aus                                            
81 USA                                            
84 Swi                                            
79 RSA                                            
81 RSA                                            
86 PRC                                            
86 USA                                            
86 USA                                            
86 USA                                            
87 USA                                            
87 USA                                            
88 Can                                            

match(s, r [, arr])返回的位置s其中正則表達式r發生並設定的值RSTARTRLENGTH 。如果提供了參數arr ,則返回數組arr ,其中元素設置為匹配的帶括號的子表達式。 arr第0個元素匹配設置為整個正則表達式匹配。表達式arr[n, "start"]arr[n, "length"]提供每個匹配子字符串的起始位置和長度。

更多字符串函數:

sub(/regexp/, "newstring"[, target])
gsub(/regexp/, "newstring"[, target])
toupper("string")
tolower("string")

聲明

一個簡單的陳述通常是以下任何一種:

variable = expression 
print [ expression-list ] 
printf format [ , expression-list ] 
next # skip remaining patterns on this input line
exit # skip the rest of the input

如果stat1stat2是語句,則以下內容也是語句:

{stat}

{stat1;  stat2}

{stat1 
stat2}

if ( conditional ) statement [ else statement ]

以下標準C-like是構造語句:

if ( conditional ) statement [ else statement ]
while ( conditional ) statement
for ( expression ; conditional ; expression ) statement
break    # usual C meaning 
continue # usual C meaning 

用於打印可變長度描述元素的C樣式循環,從字段4開始:

# awk '{out=""; for(i=4;i<=NF;i++){out=out" "$i}; print out}' coins.txt
USA American Eagle                    
Austria-Hungary Franz Josef 100 Korona
USA ingot                             
Switzerland ingot                     
RSA Krugerrand                        
RSA Krugerrand                        
PRC Panda                             
USA Liberty dollar                    
USA Liberty 5-dollar piece            
USA Liberty 50-cent piece             
USA Constitution dollar               
USA Constitution 5-dollar piece       
Canada Maple Leaf

請注意, i被初始化為0。

如果條件和計算應用於通用字段:

# awk '/gold/ {if($3<1980) print $0 "$" 425*$2}' coins.txt    
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona      $425
gold     1    1979  RSA                 Krugerrand                  $425   

AWK可執行腳本

#!/usr/bin/gawk -f
# This is a comment
(pattern) {action}
...

傳遞shell變量

# var="hello"
# awk -v x="$var" 'BEGIN {print x}'
hello