UNIX 粘贴列并为所有缺失值插入零

bio*_*han 5 awk text-processing paste

我想合并包含不同行数但列数相同的两个 txt 文件中的特定列(如下所示):

  file1:
  xyz   desc1   12
  uvw   desc2   55
  pqr   desc3   12

  file2:
  xyz   desc1   56
  uvw   desc2   88


  Preferred output:
  xyz   desc1   12  56
  uvw   desc2   55  88
  pqr   desc3   12   0
Run Code Online (Sandbox Code Playgroud)

目前我使用 awk 作为粘贴命令:

  paste <(awk '{print $1}' file1) <(awk '{print $2}' file1) <(awk '{print $3}' file1) <(awk '{print $3}' file2) 
Run Code Online (Sandbox Code Playgroud)

但这似乎只合并重叠的列。awk 中有没有办法插入零而不是省略行本身?

我需要将 100 个文件组合在一起,这样我的输出文件将包含 102 列。

Tho*_*hor 3

如果列顺序很重要,即来自同一文件的数字应保留在同一列中,则需要在读取不同文件时添加填充。这是使用 GNU awk 的一种方法:

合并.awk

# Set k to be a shorthand for the key
{ k = $1 SUBSEP $2 }

# First element with this key, add zeros to align it with other rows
!(k in h) {
  for(i=1; i<=ARGIND-1; i++)
    h[k] = h[k] OFS 0 
}

# Remember the data element
{ h[k] = h[k] OFS $3 }

# Before moving to the next file, ensure that all rows are aligned
ENDFILE {
  for(k in h) {
    if(split(h[k], a) < ARGIND)
      h[k] = h[k] OFS 0
  }
}

# Print out the collected data
END {
  for(k in h) {
    split(k, a, SUBSEP)
    print a[1], a[2], h[k]
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是一些测试文件:f1f2和:f3f4

$ tail -n+1 f[1-4]
==> f1 <==
xyz desc1 21
uvw desc2 22
pqr desc3 23

==> f2 <==
xyz desc1 56
uvw desc2 57

==> f3 <==
xyz desc1 87
uvw desc2 88

==> f4 <==
xyz desc1 11
uvw desc2 12
pqr desc3 13
stw desc1 14
arg desc2 15
Run Code Online (Sandbox Code Playgroud)

测试1

awk -f merge.awk f[1-4] | column -t
Run Code Online (Sandbox Code Playgroud)

输出:

pqr  desc3  23  0   0   13
uvw  desc2  22  57  88  12
stw  desc1  0   0   0   14
arg  desc2  0   0   0   15
xyz  desc1  21  56  87  11
Run Code Online (Sandbox Code Playgroud)

测试2

awk -f merge.awk f2 f3 f4 f1 | column -t
Run Code Online (Sandbox Code Playgroud)

输出:

pqr  desc3  0   0   13  23
uvw  desc2  57  88  12  22
stw  desc1  0   0   14  0
arg  desc2  0   0   15  0
xyz  desc1  56  87  11  21
Run Code Online (Sandbox Code Playgroud)

编辑:

如果输出应以制表符分隔,请相应地设置输出字段分隔符:

awk -f merge.awk OFS='\t' f[1-4]
Run Code Online (Sandbox Code Playgroud)