处理两个文件时在AWK中使用数组

处理两个文件时在AWK中使用数组,awk,Awk,我有两个文件,我用下面的代码合并了它们 file1 ------------------------------- 1 a t p bbb 2 b c f aaa 3 d y u bbb 2 b c f aaa 2 u g t ccc 2 b j h

我有两个文件,我用下面的代码合并了它们

file1
-------------------------------
1      a      t      p      bbb  
2      b      c      f      aaa  
3      d      y      u      bbb  
2      b      c      f      aaa  
2      u      g      t      ccc  
2      b      j      h      ccc

file2
--------------------------------
1   11   bbb  
2   22   ccc  
3   33   aaa  
4   44   aaa  
我使用下面的代码合并了这两个基于文件的密钥

awk 'NR==FNR{a[$3]=$0;next;}{for(x in a){if(x==$5) print $1,$2,$3,$4,a[x]};  
我的问题是如何在变量或数组中保存$2的file2,并在[x]之后再次打印。
我期望的结果是:

1 a t p 1   11  bbb  11  
2 b c f 3   33  aaa  33  
2 b c f 4   44  aaa  44  
3 d y u 1   11  bbb  11  
2 b c f 3   33  aaa  33  
2 b c f 4   44  aaa  44  
2 u g t 2   22  ccc  22  
2 b j h 2   22  ccc  22  
如您所见,前7列是我的合并代码的结果。我需要将最后一列(a[x]的字段2])添加到我的结果中

重要:


我的下一个问题是,如果我有.awk文件,我如何使用一些bash脚本代码,如(
|column-t
)或将结果发送到文件(
awk…>result.txt
)?我总是在命令提示符中使用这些代码。我可以在.awk文件的代码中使用它们吗?

要实现您的要求,请在处理第一个文件的整行之后保存第二个字段,使用
a[$3]=$0/s$2
。对于第二个问题,
awk
有一个变量来分隔输出中的字段,它是OFS,为它分配一个制表器并使用它。您的脚本如下所示:

awk '
    BEGIN { OFS = "\t"; } 
    NR==FNR{
        a[$3]=$0 OFS $2;
        next;
    }
    {
        for(x in a){
            if(x==$5) print $1,$2,$3,$4,a[x]
        } 
    }
' file2 file1
这将产生:

1       a       t       p       1   11   bbb    11
2       b       c       f       4   44   aaa    44
3       d       y       u       1   11   bbb    11
2       b       c       f       4   44   aaa    44
2       u       g       t       2   22   ccc    22                                                                                                                                                                                           
2       b       j       h       2   22   ccc    22

您当前的脚本是:

awk 'NR==FNR { a[$3]=$0; next }
             { for (x in a) { if (x==$5) print $1,$2,$3,$4,a[x] } }'
(实际上,原稿缺少第二个图案/动作对的第二个右括号。)

似乎在处理
file1
之前先处理
file2

在第二个代码中不应该需要循环。通过在第一阶段使用拆分,您可以使自己的生活更轻松,以保持所需的值:

awk 'NR==FNR { c1[$3] = $1; c2[$3] = $2; next }
             { print $1, $2, $3, $4, c1[$5], c2[$5], $5, c2[$5] }'
您可以将其升级以检查是否定义了
c1[$5]
c2[$5]
,如果未定义,则可能跳过该行

给定输入文件,输出为:

1 a t p 1 11 bbb 11
2 b c f 4 44 aaa 44
3 d y u 1 11 bbb 11
2 b c f 4 44 aaa 44
2 u g t 2 22 ccc 22
2 b j h 2 22 ccc 22
给定或获取列间距,这是要求的。可以使用
printf
而不是
print
来固定列间距,或者将s设置为tab,或者

第1列和第2列的
c1
c2
符号适用于两列。如果需要更多,则可能应使用2D数组表示法:

awk 'NR==FNR { for (i = 1; i <= NF; i++) col[i,$3] = $i; next }
             { print $1, $2, $3, $4, col[1,$5], col[2,$5], $5, col[2,$5] }'

awk'NR==FNR{for(i=1;i只需将所有
file2
添加到一个数组中,并使用
split
保存所需的位:

awk 'FNR==NR { two[$0]++; next } { for (i in two) { split(i, one); if (one[3] == $NF) print $1,$2,$3,$4, i, one[2] } }' file2 file1
结果:

1 a t p 1   11   bbb   11
2 b c f 3   33   aaa   33
2 b c f 4   44   aaa   44
3 d y u 1   11   bbb   11
2 b c f 3   33   aaa   33
2 b c f 4   44   aaa   44
2 u g t 2   22   ccc   22
2 b j h 2   22   ccc   22
1  a  t  p  1  11  bbb  11
2  b  c  f  3  33  aaa  33
2  b  c  f  4  44  aaa  44
3  d  y  u  1  11  bbb  11
2  b  c  f  3  33  aaa  33
2  b  c  f  4  44  aaa  44
2  u  g  t  2  22  ccc  22
2  b  j  h  2  22  ccc  22
关于最后一个问题,您还可以在
awk
中添加“管道”和“写入”。下面是管道到
列-t
的示例:

script.awk的内容

FNR==NR { 
    two[$0]++
    next
}

{
    for (i in two) {
        split(i, one)
        if (one[3] == $NF) { 
            print $1,$2,$3,$4, i, one[2] | "column -t"
        }
    }
}
像这样运行:
awk-f script.awk file2 file1

编辑:

将以下内容添加到shell脚本:

results=$(awk '

    FNR==NR {
        two[$0]++
        next
    }

    {
        for (i in two) {
            split(i, one)
            if (one[3] == $NF) {
                print $1,$2,$3,$4, i, one[2] | "column -t"
            }
        }
    }
' $1 $2)

echo "$results"
运行方式如下:

./script.sh file2.txt file1.txt
结果:

1 a t p 1   11   bbb   11
2 b c f 3   33   aaa   33
2 b c f 4   44   aaa   44
3 d y u 1   11   bbb   11
2 b c f 3   33   aaa   33
2 b c f 4   44   aaa   44
2 u g t 2   22   ccc   22
2 b j h 2   22   ccc   22
1  a  t  p  1  11  bbb  11
2  b  c  f  3  33  aaa  33
2  b  c  f  4  44  aaa  44
3  d  y  u  1  11  bbb  11
2  b  c  f  3  33  aaa  33
2  b  c  f  4  44  aaa  44
2  u  g  t  2  22  ccc  22
2  b  j  h  2  22  ccc  22

@Birei..谢谢亲爱的Birei..实际上我想将其保存到变量或数组中,以便将来进行算术运算并计算每个字段的数目。例如,我想说如果$2(文件1的)==11,那么…@steve..亲爱的steve..当我在bash脚本中使用您的代码时,它会给我错误..请告诉我下面的命令中的错误在哪里$(awk-f'FNR==NR{two[$0]++next}{for(i-in-two){split(i,one,FS)if(one[3]==NF){print$1,2,3,4,i,one[2]}}{$file1$file2)echo-e$command |列-t@mohammad:我发现了错误。您应该使用
$1
$2
(shell参数)而不是
$file1
$file2
。请查看我的更新。已修复。