解析一个文件,其中包含来自其他文件的多个数据

解析一个文件,其中包含来自其他文件的多个数据

我想根据 a.txt 中的 3 个数据(A、B、num : xxx)选择 b.txt 中的行。

a.txt

A B num : 580
A B num : 581
A B num : 582

b.txt

10 E1 A Z1 B Z2 num : 580 Z3 582 Z4
11 E2 C Z1 B Z2 num : 581 Z3 580 Z4
12 E3 A Z1 B Z2 num : 581 Z3 580 Z4
14 E3 S Z1 B Z2 num : 582 Z3 581 Z4
15 E2 A Z1 B Z2 num : 582 Z3 581 Z4

输出

10 E1 A Z1 B Z2 num : 580 Z3 582 Z4
12 E3 A Z1 B Z2 num : 581 Z3 580 Z4
15 E2 A Z1 B Z2 num : 582 Z3 581 Z4

我的代码

awk 'NR==FNR{pattern[$0];next} ($3 && $5 && "$7 $8 $9" in pattern)' a.txt b.txt > GoodFile.txt

这有什么问题吗?谢谢。

答案1

关联数组的键pattern字符串连接字段和字段分隔符,即

$ awk 'NR==FNR{pattern[$0]; next} $3" "$5" "$7" "$8" "$9 in pattern' a.txt b.txt
10 E1 A Z1 B Z2 num : 580 Z3 582 Z4
12 E3 A Z1 B Z2 num : 581 Z3 580 Z4
15 E2 A Z1 B Z2 num : 582 Z3 581 Z4

或者也许更稳健(因为它不假设分隔符是a.txt单个空格),利用明确的SUBSEPawk 变量正如埃德·莫顿建议的那样:

awk 'NR==FNR{pattern[$1,$2,$3,$5]; next} ($3,$5,$7,$9) in pattern' a.txt b.txt

答案2

利用GNU sed打开的扩展正则表达式模式-E和关闭的自动打印模式空间-n,我们可以如图所示解决它。

首先,我们定义一些辅助 shell 变量来简化 sed 代码的编写。

$ f='(\S+)' g='\s+\S+\s+' fg="$f$g"
$ Ss='\S+\s+' fs="$f\s+"
$ re="$Ss $Ss $fg $fg $fs $fs $fs"
$ sed -En "
    s/$f/&/6;tb
    s/\s+/ /g;s/^ | \$//g
    H;d
    :b;G
    \#^${re// /}.*\n\1 \2 \3 \4 \5(\n|$)#P
" a.txt b.txt

¶ 首先,我们通过存在的第 6 个非空格块来识别来自 a.txt 或 b.txt 的行。如果是,则为文件 b.txt,我们跳转到 sed 代码中的标签 b。

¶ 否则,对于文件 a.txt,我们修剪行并压缩空格。然后存放。

¶ 对于文件 b.txt 中的行,我们插入 $re shell 变量,该变量是根据 b.txt 的行结构编写的。另外,在编写它时,为了清晰起见,我们在其中撒了空格,现在我们必须将其删除。P如果 b.txt 的块编号 3、5、7,8 和 9 在 a.txt 的一行中的任何位置找到,我们将打印模式空间的前导部分。

相关内容