2015-10-18 98 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的解决方案的投票虽然:-)