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

使用AWK处理来自多个文件的输入,awk,Awk,许多人通过发布以下解决方案一次唤醒多个输入文件而非常有帮助: $ 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} 这里我们处理第一个输入(文件2)。比方说,FS是空间,我们构建一个数组(a),索引是column1,值是column2”

许多人通过发布以下解决方案一次唤醒多个输入文件而非常有帮助:

$ 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}
这里我们处理第一个输入(文件2)。比方说,FS是空间,我们构建一个数组(
a
),索引是column1,值是
column2”“column3
FNR==NR,接下来的
意味着,这部分代码只对file2起作用。你可以目瞪口呆地检查NR和FNR是什么

{ print $0, a[$1]}' file2 file1
NR!=FNR
是时候处理第二个输入文件1了。这里我们打印file1的行,并以column1作为索引,找出数组(a)print中的值。换句话说,file1和file2在两个文件中都由column1连接

对于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
检查的技巧。

我在谷歌上找到了这个问题/答案,它似乎是指在另一个问题()中找到的一个非常具体的数据集。下面是我一直在寻找的答案(我想大多数人都会这样),也就是说,使用AWK将两个不同文件中的每一行连接起来。虽然您可能会使用一些UNIX实用程序,如joinpaste,但如果您希望的输出不同,AWK显然会更灵活、更强大,方法是使用if语句,或更改OFS(根据实用程序的不同,这可能更难实现;请参见下文)例如,以一种更具表现力的方式更改输出(shell脚本编写人员的一个重要考虑事项)

对于简单的逐行连接:

awk'FNR==NR{a[FNR”“]=$0;下一个}{print a[FNR”“],$0}文件1文件2

这通过使用隐式类型转换模拟数字索引数组(AWK仅具有关联数组)的功能。这是相对表达和容易理解

使用两个名为test1和test2的文件,并使用以下行:

测试1:

line one
line two
line three
测试2:

line four
line five
line six
我得到这个结果:

line one line four
line two line five
line three line six
line one...line four
line two...line five
line three...line six
根据要在输出中的列之间联接值的方式,可以选择适当的输出字段分隔符。下面是一个用椭圆(…)分隔列的示例:

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
line one...line four
line two...line five
line three...line six

我希望这至少能激励你们利用AWK的力量

不久前,我偶然发现了一个很好的解决方案,可以同时处理多个文件。方法是使用以下方法将文件保存在内存中:

FILENAME==ARGV[1] {  file2array[FNR] = $0 ; next }
FILENAME==ARGV[2] {  file1array[FNR] = $0 ; next }
对于后期数据处理,最好保存行数,因此:

FILENAME==ARGV[1] {  file2array[FNR] = $0 ; f2rows = FNR ; next }
FILENAME==ARGV[2] {  file1array[FNR] = $0 ; f1rows = FNR ; next }
f2行
f1行
将保留最后一行的位置


它有更多的代码,但是如果您想要更复杂的数据处理,我认为这是更好的方法。此外,以前的方法按顺序处理输入,因此如果您需要同时执行一些依赖于两个文件数据的计算,您将无法执行,而使用这种方法,您可以对两个文件执行所有操作。

Kent,非常好的解释;非常感谢你。我没有意识到'FNR==NR'正在形成一种'if'语句。这正是我前进所需要的。非常感谢您抽出时间来帮忙!如果目标只是并排连接列,那么使用
paste
命令就非常简单。而其他答案适用于两个文件(如果只是第一个需要特殊处理的文件,则适用于多个文件)——由于可以与任意数量的文件一起使用,因此对该文件进行了升级。