使用AWK处理来自多个文件的input

许多人通过发布以下解决scheme来一次AWK多个input文件非常有帮助:

$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1 

这很好,但我想知道如果有人能向我解释为什么? 我发现AWK语法有点难以理解,希望有人不介意打破我的代码片断。 感谢您的时间和帮助!

 awk 'FNR==NR{a[$1]=$2 FS $3;next} 

这里我们处理第一个input(file2)。 比如说FS是空间,我们build立一个数组( a ),索引是column1,value是column2 " " column3FNR==NR and next就是说这部分代码只对file2有效。 你可以检查什么是NR和FNR

 { print $0, a[$1]}' file2 file1 

NR != FNR时,处理第二个inputfile1。 这里我们打印file1的行,并以column1为索引,找出array(a)中的值print。 换句话说,两个文件中的文件1和文件2都由列1连接。

对于NR和FNR,不久,

 1st input has 5 lines 2nd input has 10 lines, NR would be 1,2,3...15 FNR would be 1...5 then 1...10 

你会看到FNR==NR检查的技巧。

我在Google上发现了这个问题/答案,它似乎是指在另一个问题( 如何使用AWK合并两个文件? )中find的非常具体的数据集。 接下来是我正在寻找的答案(我想大多数人会这样做),也就是简单地使用AWK连接来自两个不同文件的每一行。 尽pipe你可以使用一些UNIX工具,例如join或者paste ,但是如果你想要的输出不同,使用if语句或者改变OFS (根据实用工具可能更难实现,AWK显得更加灵活和强大;见下面),例如,以更富有performance力的方式改变输出(shell脚本的一个重要考虑因素)。

对于简单的逐行连接:

awk 'FNR==NR { a[FNR""] = $0; next } { print a[FNR""], $0 }' file1 file2

这通过使用隐式types转换来模拟数字索引数组(AWK只有关联数组)的function。 这是相对expression和易于理解。

使用两个名为test1和test2的文件,内容如下:

testing1:

 line one line two line three 

testing2:

 line four line five line six 

我得到这个结果:

 line one line four line two line five line three line six 

根据您希望如何连接输出中的列之间的值,可以select适当的输出字段分隔符。 下面是一个用椭圆(…)分隔列的例子:

awk 'BEGIN { OFS="..."} FNR==NR { a[(FNR"")] = $0; next } { print a[(FNR"")], $0 }' test1 test2

产生这个结果:

 line one...line four line two...line five line three...line six 

我希望至less这能激发你们所有人利用AWK的力量!