awk的資料輸入有兩個來源,標準輸入和檔案,後一種方式支援多個檔案。
如:
1. shell的Pathname Expansion方式:awk '{...}' *.txt
# *.txt先被shell解釋,替換成目前的目錄下的所有*.txt,
# 如目前的目錄有1.txt和2.txt,則命令最終為awk '{...}' 1.txt 2.txt
2. 直接指定多個檔案: awk '{...}' a.txt b.txt c.txt ...
# awk對多檔案的處理流程是,依次讀取各個檔案內容,如上例,先讀a.txt,再讀b.txt....
那麼,在多檔案處理的時候,如何判斷awk目前讀的是哪個檔案,而依次做對應的操作呢?
########################
#
# 處理 2 個檔案
#
########################
當awk讀取的檔案只有兩個的時候,比較常用的有兩種方法:
(1) 一種是 awk 'NR==FNR{...}NR>FNR{...}' file1 file2 或 awk 'NR==FNR{...}NR!=FNR{...}' file1 file2
(2) 另一種是 awk 'NR==FNR{...;next}{...}' file1 file2
當awk讀取的檔案只有兩個的時候,比較常用的有兩種方法:
(1)一種是
awk 'NR==FNR{...}NR>FNR{...}' file1 file2
|
或
awk 'NR==FNR{...}NR!=FNR{...}' file1 file2
|
(2) 另一種是
awk 'NR==FNR{...;next}{...}' file1 file2
|
瞭解了FNR和NR這兩個awk內建變數的意義就很容易知道這兩種方法是如何運作的
FNR The input record number in the current input file. #已讀入當前檔案的記錄數
NR The total number of input records seen so far. #已讀入的總記錄數
next Stop processing the current input record. The next input record is read and processing starts over with the first pattern in the AWK program. If the end of the input data is reached, the END block(s), if any, are executed.
|
awk 'NR==FNR{...}NR>FNR{...}' file1 file2
|
# 讀入file1的時候,已讀入file1的記錄數FNR一定等於awk已讀入的總記錄數NR,因為file1是awk讀入的首個檔案,故讀入file1時執行前一個命令塊{...}
# 讀入file2的時候,已讀入的總記錄數NR一定>讀入file2的記錄數FNR,故讀入file2時執行後一個命令塊{...}
awk 'NR==FNR{...;next}{...}' file1 file2
|
# 讀入file1時,滿足NR==FNR,先執行前一個命令塊,但因為其中有next命令,故後一個命令塊{...}是不會執行的
# 讀入file2時,不滿足NR==FNR,前一個命令塊{..}不會執行,只執行後一個命令塊{...}
########################
#
# 處理 多個 檔案
#
########################
當awk處理的檔案超過兩個時,顯然上面那種方法就不適用了。因為讀第3個檔案或以上時,也滿足NR>FNR (NR!=FNR),顯然無法區分開來,所以就要用到更通用的方法了:
1. ARGIND # 當前被處理參數標誌
awk 'ARGIND==1{...}ARGIND==2{...}ARGIND==3{...}... ' file1 file2 file3 ...
|
2. ARGV # 命令列參數數組
awk 'FILENAME==ARGV[1]{...}FILENAME==ARGV[2]{...}FILENAME==ARGV[3]{...}...' file1 file2 file3 ...
|
3. 把檔案名稱直接加入判斷
awk 'FILENAME=="file1"{...}FILENAME=="file2"{...}FILENAME=="file3"{...}...' file1 file2 file3 ...
|
########################
#
# 例子 1
#
########################
現有file1,file2 兩個檔案。檔案file1有2列,內容如:
no1 name1 no2 name2 no3 name2 no4 name3 no5 name4 no6 name4 no7 name4 no8 name5 no9 name6 no10 name6
|
檔案file2 有6列,部分有空格,內容如下:
name1 data1 dada2 data3 data4 dada5 name2 dada6 data7 dada8 name3 data9 dada10 data11 dada12 name4 data13 dada14 name5 data15 dada16 name6 data17 data18
|
如果file1的第2列跟file2的第1列匹配,則將兩條資料合併成一條,合并後的資料應該是這樣的:
no1 name1 data1 dada2 data3 data4 dada5 no2 name2 dada6 data7 dada8 no3 name2 dada6 data7 dada8 no4 name3 data9 dada10 data11 dada12 no5 name4 data13 dada14 no6 name4 data13 dada14 no7 name4 no8 name5 data15 dada16 no9 name6 data17 data18 no10 name6 data17 data18
|
程式:
awk 'NR==FNR{a[$1]=$0}NR>FNR{print $1" "a[$2]}' file2 file1
|
########################
#
# 例子 2
#
########################
file1:
sina.com 52.5 sohu.com 42.5 baidu.com 35
|
file 2:
www.news.sina.com sina.com 80 www.over.sohu.com baidu.com 20 www.fa.baidu.com sohu.com 50 www.open.sina.com sina.com 60 www.sport.sohu.com sohu.com 70 www.xxx.sohu.com sohu.com 30 www.abc.sina.com sina.com 10 www.fa.baidu.com baidu.com 50 www.open.sina.com sina.com 60 www.over.sohu.com sohu.com 20
|
合并的結果:
www.news.sina.com sina.com 80 52.5 www.over.sohu.com baidu.com 20 42.5 www.fa.baidu.com sohu.com 50 35 www.open.sina.com sina.com 60 52.5 www.sport.sohu.com sohu.com 70 42.5 www.xxx.sohu.com sohu.com 30 42.5 www.abc.sina.com sina.com 10 52.5 www.fa.baidu.com baidu.com 50 35 www.open.sina.com sina.com 60 52.5 www.over.sohu.com sohu.com 20 42.5
|
程式:
awk 'NR==FNR{a[$1]=$2;next}{print $0,a[$2]}' file1 file2
原文地址 http://blog.chinaunix.net/u1/45949/showart_2327975.html