【问题标题】:How to match two different length and different column text file with header using join command in linux如何在linux中使用join命令将两个不同长度和不同列的文本文件与标题匹配
【发布时间】:2020-12-08 19:20:51
【问题描述】:

我有两个不同长度的文本文件 A.txt 和 B.txt

A.txt 看起来像:

ID  pos  val1  val2  val3
1   2    0.8     0.5   0.6
2   4    0.9     0.6   0.8
3   6    1.0     1.2   1.3
4   8    2.5     2.2   3.4
5   10   3.2     3.4   3.8

B.txt 看起来像:

pos category
2    A
4    B
6    A
8    C
10   B

我想在两个文件中匹配 pos 列并希望输出像这样

ID  catgeory  pos  val1  val2  val3
1      A       2    0.8     0.5   0.6
2      B       4    0.9     0.6   0.8
3      A       6    1.0     1.2   1.3
4      C       8    2.5     2.2   3.4
5      B       10   3.2     3.4   3.8

我使用了join函数join -1 2 -2 1 <(sort -k2 A.txt) <(sort -k1 B.txt) > C.txt

C.txt 没有标题

    1      A       2    0.8     0.5   0.6
    2      B       4    0.9     0.6   0.8
    3      A       6    1.0     1.2   1.3
    4      C       8    2.5     2.2   3.4
    5      B       10   3.2     3.4   3.8

我想从连接函数中获取带有标题的输出。请帮帮我

提前致谢

【问题讨论】:

  • 当我运行你的join 命令时,我得到完全不同的列顺序和 C.txt 中最后一行的标题。

标签: linux shell join


【解决方案1】:

如果您对awk 没问题,请尝试关注。使用 GNU awk 中的示例编写和测试。

awk 'FNR==NR{a[$1]=$2;next} ($2 in a){$2=a[$2] OFS $2} 1' B.txt A.txt | column -t

说明:为上述添加详细说明。

awk '                       ##Starting awk program from here.
FNR==NR{                    ##Checking condition FNR==NR which will be TRUE when B.txt is being read.
  a[$1]=$2                  ##Creating array a with index of 1st field and value is 2nd field of current line.
  next                      ##next will skip all further statements from here.
}
($2 in a){                  ##Checking condition if 2nd field is present in array a then do following.
  $2=a[$2] OFS $2           ##Adding array a value along with 2nd field in 2nd field as per output.
}
1                           ##1 will print current line.
' B.txt A.txt | column -t   ##Mentioning Input_file names and passing awk program output to column to make it look better.

【讨论】:

  • 谢谢,@ravinderSingh13 但在连接函数中看起来一样
  • @Jammy,当我运行命令 join -1 2 -2 1 <(sort -k2 A.txt) <(sort -k1 B.txt) 时,我可以看到标题即将到来,但在最后一行,但您提到您的问题中根本没有标题,请您澄清一下?
【解决方案2】:

如您所愿...完全有可能仅使用 GNU join 获得所需的输出:

$ join -1 2 -2 1 <(sort -k2 -g A.txt)  <(sort -k1 -g B.txt) -o 1.1,2.2,1.2,1.3,1.4,1.5
ID category pos val1 val2 val3
1 A 2 0.8 0.5 0.6
2 B 4 0.9 0.6 0.8
3 A 6 1.0 1.2 1.3
4 C 8 2.5 2.2 3.4
5 B 10 3.2 3.4 3.8
$

获得正确输出的关键是使用sort -g 选项,并使用-o 选项指定join 输出列顺序。

要“漂亮地打印”输出,请通过管道传送到 column -t

$ join -1 2 -2 1 <(sort -k2 -g A.txt)  <(sort -k1 -g B.txt) -o 1.1,2.2,1.2,1.3,1.4,1.5 | column -t
ID  category  pos  val1  val2  val3
1   A         2    0.8   0.5   0.6
2   B         4    0.9   0.6   0.8
3   A         6    1.0   1.2   1.3
4   C         8    2.5   2.2   3.4
5   B         10   3.2   3.4   3.8
$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 2014-06-11
    • 2017-06-24
    • 1970-01-01
    • 2023-01-22
    • 2013-05-23
    • 2021-11-14
    相关资源
    最近更新 更多