基于指定列顺序匹配,提取文件中连续匹配行的技术问询
需求:按指定列顺序从文件2提取连续匹配行块
现有两个文件,需要基于某一指定列(比如示例中的第2列或第4列),从文件2中提取与文件1该列顺序完全一致的连续行块。两个文件均按第1列的标识符排序,但两文件的标识符不对应,且待匹配列的条目并非唯一。
之前尝试过以下awk命令:
awk 'FNR==NR{ a[$2]=$2;next } ($2 in a)' file1 file2 > output
但这个命令仅适用于待匹配列条目唯一的场景,无法满足当前需求。
示例1
file1
x 1 x 2 x 3
file2
y 5 y 1 y 2 y 3 y 6
期望输出
y 1 y 2 y 3
真实数据示例
File1
ATOM 13 O ALA A 2 37.353 35.331 -19.903 1.00 71.02 O ATOM 18 O TRP A 3 38.607 32.133 -18.273 1.00 69.13 O
File2
ATOM 1 N MET A 1 42.218 38.990 -18.511 1.00 64.21 N ATOM 10 CA ALA A 2 38.451 37.475 -20.033 1.00 71.02 C ATOM 13 O ALA A 2 37.353 35.331 -19.903 1.00 71.02 O ATOM 18 O TRP A 3 38.607 32.133 -18.273 1.00 69.13 O ATOM 29 CA ILE A 4 38.644 33.633 -15.907 1.00 72.47 C
解决方案(以匹配第2列为例)
可以用awk记录file1的目标序列,然后在file2中遍历寻找连续匹配的行块:
awk -v col=2 ' FNR == NR { seq[++n] = $col; next; } { if ($col == seq[pos+1]) { pos++; buf[pos] = $0; if (pos == n) { for (i=1; i<=n; i++) print buf[i]; exit; # 找到第一个匹配块就退出,若要找所有可去掉exit } } else { pos = 0; if ($col == seq[1]) { pos = 1; buf[1] = $0; } } } ' file1 file2 > output
说明
-v col=2指定要匹配的列(真实数据若要匹配第4列,改为col=4即可)- 先读取file1,把指定列的内容按顺序存入数组
seq - 遍历file2时,跟踪当前匹配序列的位置
pos:- 若当前行指定列匹配序列的下一个元素,就存入缓冲区
buf并推进pos - 当
pos等于序列长度n时,输出缓冲区所有行(即完整连续匹配块) - 若中途不匹配则重置
pos,如果当前行刚好匹配序列第一个元素,则重新开始计数
- 若当前行指定列匹配序列的下一个元素,就存入缓冲区
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

