如何用Awk提取满足双条件的行:第6列>5且第1列有5个连续数
提取满足双重条件的文本行
需求描述
需从给定文本数据中提取同时符合以下两个条件的行:
- 第6列数值大于5;
- 第1列的数字属于至少包含5个连续数值的组。
输入数据
08 V 3.8 0.0 23.456 60.459 60.459 09 M 4.4 0.0 24.960 72.301 72.301 10 L 4.4 0.0 25.301 95.197 95.197 11 L 1.9 0.0 25.410 99.173 99.173 12 L 1.7 0.0 25.484 99.862 99.862 104 V 7.1 0.0 0.374 5.225 5.225 105 L 0.7 0.0 0.374 5.119 5.119 169 V 4.6 0.1 0.000 31.658 1.658 170 S 5.7 0.0 0.000 32.117 1.117 171 S 5.7 0.0 0.000 32.117 5.001 260 Y 4.8 0.0 0.342 54.178 54.178 261 S 4.1 0.0 0.144 67.833 67.833 262 I 8.4 0.0 0.000 87.300 87.300 263 I 9.5 0.0 0.000 88.950 88.950 264 I 11.3 0.1 0.000 89.070 89.070
期望输出
08 V 3.8 0.0 23.456 60.459 60.459 09 M 4.4 0.0 24.960 72.301 72.301 10 L 4.4 0.0 25.301 95.197 95.197 11 L 1.9 0.0 25.410 99.173 99.173 12 L 1.7 0.0 25.484 99.862 99.862 260 Y 4.8 0.0 0.342 54.178 54.178 261 S 4.1 0.0 0.144 67.833 67.833 262 I 8.4 0.0 0.000 87.300 87.300 263 I 9.5 0.0 0.000 88.950 88.950 264 I 11.3 0.1 0.000 89.070 89.070
完整Awk命令
需要分两次扫描数据:第一次识别符合要求的连续ID组,第二次筛选满足双重条件的行,命令如下:
LC_ALL=C awk ' NR == FNR { id = $1 + 0 # 转换为数值,消除前导零干扰 if (prev_id + 1 == id) { current_seq_len++ } else { current_seq_len = 1 } seq_start[id] = (current_seq_len == 1) ? id : seq_start[prev_id] seq_len[id] = current_seq_len prev_id = id next } $6 > 5 { id = $1 + 0 # 验证当前ID所属连续序列长度是否≥5 if (seq_len[id] >= 5 || seq_len[seq_start[id] + 4] >= 5) { print } } ' input input
命令说明
- 第一次扫描(NR == FNR):
- 将第1列的ID转为数值,避免"08"这类带前导零的字符串影响连续性判断。
- 跟踪连续ID序列的长度:若当前ID是前一个ID+1,则序列长度加1,否则重置为1。
- 用
seq_start数组记录每个ID所属连续序列的起始ID,seq_len数组记录对应序列的长度。
- 第二次扫描:
- 先筛选出第6列数值大于5的行。
- 对这些行,检查其ID所属的连续序列长度是否至少为5(通过判断序列起始ID+4对应的序列长度≥5,确保序列包含至少5个连续数值)。
- 符合条件则打印该行。
内容的提问来源于stack exchange,提问作者Jalan
相关产品推荐
相关产品推荐

