如何从无空格固定格式文件按指定列匹配ID提取目标字段?
问题与解决方案
问题背景
有一个无空格固定格式的大文件file1,内容如下:
0808563800555550000367120000500000 0005555566369330000078020000500000 01066666780000000008933600009000005635 0904251263088000000786590056500000 0000469011009904440425120444444440
需要提取每行第4-8、11-15、20-24字符段,但仅保留那些第4-8字段在file2的ID列表中的行。file2内容:
55555 42512
期望输出:
55555 36933 07802 42512 08800 78659
尝试过cut+grep组合:
cut -c 4-8,11-15,20-24 file1 --output-delimiter=' ' | grep -w -F -f file2
但该命令会匹配切割后的所有列,导致结果混入其他列匹配ID的行,不符合预期。
解决方案
方案1:awk一步处理(推荐,高效无中间文件)
直接用awk加载ID列表并处理原始文件,无需中间步骤:
awk 'NR==FNR {ids[$1]=1; next} {col1=substr($0,4,5); col2=substr($0,11,5); col3=substr($0,20,5); if(ids[col1]) print col1, col2, col3}' file2 file1
- 逻辑:先把
file2的ID存入数组,再遍历file1提取对应字段,仅当第一字段在ID列表时输出。
方案2:修改grep规则,仅匹配第一列
如果坚持用cut+grep,可以给ID加上行首约束:
cut -c 4-8,11-15,20-24 file1 --output-delimiter=' ' | grep -w -F -f <(sed 's/^/^/' file2)
- 用
sed给每个ID前加^,让grep只匹配行首的第一列,避免匹配后面的字段。
方案3:先过滤再切割(更高效,适合超大文件)
先在原始文件中筛选出符合条件的行,再切割提取字段:
grep -f <(sed 's/^/.\{3\}/' file2) file1 | cut -c 4-8,11-15,20-24 --output-delimiter=' '
- 逻辑:用
sed生成匹配规则,让grep找到原始文件中第4-8位是ID的行,再用cut提取所需字段,减少后续处理的数据量。
内容的提问来源于stack exchange,提问作者Adam Majdi
相关产品推荐
相关产品推荐

