Bash - 按列加入(合并)文件

时间:2015-01-15 08:58:20

标签: linux bash file join awk

有三个带列的文件,分隔符为“|”,行中的列可能为空。我需要连接第二个和第三个文件,首先使用第一个文件中的第3列和第4列,第二个和第三个中使用第1列。

例如:

FILE1.TXT:

123456||4|11|17|A||10|B|1
123457||4|11|17|A||12||1
123458||5|11|17|A||1|Б|1
123459||6|13|17|A||1|Б|1

FILE2.TXT:

4|Forth
5|Fifth
6|Sixth

file3.txt:

11|st.|Eleventh
13|pr.|Thirteenth

我想要的输出是什么:

123456||4|Forth|11|st.|Eleventh|17|A||10|B|1
123457||4|Forth|11|st.|Eleventh|17|A||12||1
123458||5|Fifth|11|st.|Eleventh|17|A||1|Б|1
123459||6|Sixth|13|pr.|Thirteenth|17|A||1|Б|1

如何编写能够满足我需求的Bash脚本?我知道这是awt命令,但我无法编写脚本。谢谢你的回答。

3 个答案:

答案 0 :(得分:4)

您可以使用此awk命令:

awk 'BEGIN{ FS=OFS="|" }
     NR == FNR {a[$1]=$0; next}
     NR == FNR + length(a) {b[$1]=$0; next}
     {$3=b[$3]; $4=a[$4]} 1' file3.txt file2.txt file1.txt
123456||4|Forth|11|st.|Eleventh|17|A||10|B|1
123457||4|Forth|11|st.|Eleventh|17|A||12||1
123458||5|Fifth|11|st.|Eleventh|17|A||1|Б|1
123459||6|Sixth|13|pr.|Thirteenth|17|A||1|Б|1

<强>解释

  • BEGIN{ FS=OFS="|" } - 将输入和输出字段分隔符设置为管道|
  • NR == FNR - 仅对第一个文件执行此块
  • a[$1]=$0; next - 创建一个数组a,其键为$1,值为完整行
  • NR == FNR + length(a) - 仅对第二个文件执行此块
  • b[$1]=$0; next - 创建一个数组b,其键为$1,值为完整行
  • 为最后一个(第三个)文件执行下一个块{...}
  • $3=b[$3]; - 将b[$3]的值分配给第3个字段
  • $4=a[$4]; - 将a[$4]的值分配给第4个字段
  • 1 - 是打印每条记录的默认操作

答案 1 :(得分:2)

假设文件已排序:

join -t'|' -1 4 -2 1 \
     <(join -t '|' -1 3 -2 1 file1.txt file2.txt) file3.txt

如果您确实需要特定顺序的字段,请添加输出格式选项:

 -o1.2,1.3,1.1,1.11,1.4,2.2,2.3,1.5,1.6,1.7,1.8,1.9,1.10,1.11

答案 2 :(得分:1)

这是:

#!/bin/bash

while IFS='|' read c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
        do
        st1=$( fgrep "$c3" file2.txt )
        st2=$( fgrep "$c4" file3.txt )
        echo "$c1|$c2|$st1|$st2|$c5|$c6|$c7|$c8|$c9|$c10"
        done