使用Awk提取两个文件中相同CL区块的问题求助
问题:用Awk匹配两个文件中的完整CL区块并输出
需求
找出两个.cls文件里完整的相同CL区块,保存到out.txt。每个CL区块包含两行:一行是>CLx 1开头的标识行,一行是对应的lcu列表行。
文件内容
file1.cls
>CL1 1 lcu_1 lcu_2 lcu_3 >CL2 1 lcu_6 lcu_4 lcu_8
file2.cls
>CL1 1 ler_1 lcu_2 ler_3 >CL2 1 lcu_1 lcu_2 lcu_3 >CL3 1 lcu_6 lcu_4 lcu_8
期望输出
>CL1 1 lcu_1 lcu_2 lcu_3 >CL2 1 lcu_6 lcu_4 lcu_8
当前代码及问题
用了下面的Awk命令:
awk 'FNR==NR {a[$1]; next} $1 in a' file1.cls file2.cls > out.txt
但实际只输出了标识行,缺了对应的lcu列表行:
CL1 1 CL2 1
解决方案
原代码只存了标识行的第一个字段,而且只输出匹配到的标识行,没处理区块的第二行。得把整个CL区块当成一个单元来处理,下面两种方法都能解决:
方法1:按标识行关联内容行
awk ' FNR==NR { if ($0 ~ /^>CL/) { key = $0 } else { a[key] = $0 } next } $0 ~ /^>CL/ { current_key = $0 } current_key in a && $0 !~ /^>CL/ { print current_key print a[current_key] delete a[current_key] } ' file1.cls file2.cls > out.txt
逻辑说明
- 处理file1时:遇到
>CL开头的行就记为索引key,下一行内容存在数组a中,关联到这个key - 处理file2时:先记录当前的标识行current_key,遇到内容行时,检查current_key是否在a里。如果在,就输出对应的标识行和file1里的内容行,然后删掉数组里的条目避免重复输出
方法2:直接读取完整区块
如果每个区块固定是两行,用getline一次性读整个区块更简洁:
awk ' FNR==NR { block = $0 ORS getline block = block $0 a[$0] = block next } $0 ~ /^>CL/ { getline if ($0 in a) { print a[$0] } } ' file1.cls file2.cls > out.txt
逻辑说明
- 处理file1时:先读标识行,再读下一行内容,把整个区块存起来,用内容行作为匹配的键
- 处理file2时:遇到标识行就读下一行内容,检查内容行是否在file1的区块里,是的话就输出对应的完整区块
内容的提问来源于stack exchange,提问作者Alex Silvestrini
相关产品推荐
相关产品推荐

