2015-10-18 127 views
1

我是awk新手,並且承認不瞭解FNR NR如何驅動文件循環。我能夠得到兩個輸入文件的工作。我需要添加另一個(inputFile3)。多輸入文件awk命令行

我在命令行中運行以下命令:

awk -f parseField.awk inputFile1.csv inputFile2.csv ./inputFile3.TXT 

目前,我遍歷inputFile3使用:

FNR!=NR {...} 

我遍歷inputFile1使用:

FNR==NR {...} 

我需要向混音中添加另一個文件(inputFile2)。我可以在我的awk腳本(parseField)中使用什麼語法來訪問第三個輸入文件?

+2

'FNR' ==「在當前輸入文件的輸入記錄編號「。 'NR' ==「到目前爲止所看到的輸入記錄總數。」所以'FNR == NR'代表第一個文件,每個文件都不同。你想用你的第三個文件做什麼? –

回答

4

要添加到@EtanReisner的好信息,您可以保留一個計數器:FNR==1 {file_number++}。這會在讀取文件的第一行時增加計數器。

總之,你可以說:

#!/bin/awk -f 

BEGIN {print "start program"} 
NR==1 {print "reading first file"} 
FNR==1 {filenum++; print "I am in file number", filenum} 
{ ... } 

如果你是在一個 GNU POSIX awkthanks Jonathan Leffler),你也可以使用FILENAME變量。或者還有ARGC變量和ARGV數組。


另見關於這個信息在Idiomatic awk

,往往是在AWK使用的另一種構建體如下:

$ awk 'NR == FNR { # some actions; next} # other condition {# other actions}' file1.txt file2.txt 

這用於處理兩個文件時。處理多個 文件時,awk會依次讀取每個文件,它們在命令行中以 的順序依次排列。無論 有多少個文件已被讀取,特殊變量NR 存儲了迄今爲止讀取的輸入記錄總數。 NR的值從1開始,總是 增加,直到程序終止。另一個變量FNR存儲從正在處理的當前文件中讀取的記錄數量 。 FNR的 值從1開始,直到達到當前文件的末尾 ,然後在讀取下一個文件的第一行時再次設置爲1,依此類推。所以,條件NR == FNR只有真正的 而awk正在讀取第一個文件。

+0

FILENAME是POSIX ['awk']的一部分(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html)。 ARGV數組和ARGC變量也是如此 - ARGV的索引從0(而不是1)開始,並且記錄的參數將「awk」和程序的選項排除在外。 –

+0

@JonathanLeffler是的,所以我建議每當'FNR == 1'時使用一個計數器是最可靠的方法。 – fedorqui

+1

我同意'FNR == 1'是檢測文件更改的好方法。你對GNU Awk的評論比需要更嚴格('FILENAME'不是GNU Awk專有的)。並且知道ARGC和ARGV存在可能會有所幫助。 –

0

不像POSIX FILENAME解決方案那麼優雅,但對於那些缺少太多特性的塵土飛揚的舊awk很方便。您可以在一對夫婦的方式將其發送到awk前操縱數據的複合語句...

選項1

首先,你可以輸出自身的filenumber每個文件之前,你發送到awk。所以,如果你的文件是這樣的:

文件1

Line 1 of 1 

文件2

Line 1 of 2 
Line 2 of 2 

文件3

Line 1 of 3 
Line 2 of 3 
Line 3 of 3 

你可以這樣做:

{ echo 1; cat file1; echo 2; cat file2; echo 3; cat file3; } 
1 
Line 1 of 1 
2 
Line 1 of 2 
Line 2 of 2 
3 
Line 1 of 3 
Line 2 of 3 
Line 3 of 3 

和管道將進入awk然後每次拿起filenumber字段數爲1

{ echo 1; cat file1; echo 2; cat file2; echo 3; cat file3; } | awk 'NF==1{file=$1;next} {print file,$0}' 
1 Line 1 of 1 
2 Line 1 of 2 
2 Line 2 of 2 
3 Line 1 of 3 
3 Line 2 of 3 
3 Line 3 of 3 

選項2

或者,你可以將文件編號編輯到每行的開頭或結尾,以便在awk之內可以使用$1,如下所示:

{ sed 's/^/1 /' file1; sed 's/^/2 /' file2; sed 's/^/3 /' file3; } 
1 Line 1 of 1 
2 Line 1 of 2 
2 Line 2 of 2 
3 Line 1 of 3 
3 Line 2 of 3 
3 Line 3 of 3 

所以,現在你可以做

{ sed 's/^/1 /' file1; sed 's/^/2 /' file2; sed 's/^/3 /' file3; } | awk '{file=$1; ...}' 

我還在爲@ fedorqui的解決方案的投票雖然:-)