【问题标题】:how to use awk to merge files with common fields and print in another file如何使用 awk 将文件与常用字段合并并打印到另一个文件中
【发布时间】:2015-02-07 04:29:35
【问题描述】:

我已经阅读了所有相关的问题,但仍然很困惑......

我有两个文件标签分开。
file1(为便于阅读添加了中断):

a 15 bac
g 10 bac
h11 bac
r 33 arq
t 12 euk

file2(为便于阅读添加了中断):

0 15 h 3 5 2 gf a a g e g s s g g 
p 33 g 4 5 2 hg 3 1 3 f 5 h 5 h 6 
g 4  r 8 j 9 jk 9 j 9 9 h t 9 k 0  

所需的输出(为可读性添加了中断):

bac 15 h 3 5 2 gf a a g e g s s g g 
arq 33 g 4 5 2 hg 3 1 3 f 5 h 5 h 6
ND g 4  r 8 j 9 jk 9 j 9 9 h t 9 k 0

就是这样。我需要打印完整的 file2 但在第一列中,只有当 file2$2 时,我才需要用 file1 的第三列替换与 file1$2 相同...
file1 大于 file2,但仍可能发生 $2 file2 不存在于 file1 中,在这种情况下打印在第一列 ND
我确定它一定很简单,但我在管理两个文件时遇到了awk 的问题。请,如果有人可以帮助我...

【问题讨论】:

  • file2的$2为10,arq的$2为10时,第二行怎么变成33?
  • 对不起。我的错。 File2 在第二行应该有 33
  • 所以最终输出是否应该跳过 file2 的第一列?

标签: bash file join awk merge


【解决方案1】:

使用这个 awk 命令:

awk 'FNR==NR{a[$2]=$3;next} {$1=(a[$2])?a[$2]:"ND"} 1' file1 file2
bac 15 h 3 5 2 gf a a g e g s s g g
arq 33 g 4 5 2 hg 3 1 3 f 5 h 5 h 6
ND 4 r 8 j 9 jk 9 j 9 9 h t 9 k 0

说明:

  • FNR==NR - 对输入中的第一个文件执行此块,即file1
  • a[$2]=$3 - 填充关联数组a,其中键为$2,值为$3,来自file1
  • next - 阅读下一行直到第一个文件上的EOF
  • 现在在file2运营
  • $1=(a[$2])?a[$2]:"ND" - 如果在数组a 中找到$2,则用a[$2] 覆盖$1,否则用文字字符串"ND"
  • 1 - 打印输出

【讨论】:

  • 非常感谢!它工作完美,只是另一个愚蠢的问题:如果分隔符字段是空格而不是制表符怎么办?
  • 默认情况下,awk 将任何空格视为字段分隔符,即空格或制表符。所以空格和制表符都可以。
【解决方案2】:

你可以试试下面的 join + awk 命令:

join -t ' ' -a2  -1 2 -2 2 test1.txt test2.txt | awk 'BEGIN { start = 5; end = 18 } { if (NF == 16) { temp = $1; $1 = "ND " $2; $2 = temp; print } else { printf("%s %s ", $3, $1); for (i=start; i<=end; i++) printf ("%s ", $i); printf("\n");}}'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多