You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于第一列提取第三列值为0的连续区间首尾行(孤立行重复输出)

问题描述

原始输入文件

1    1    1
1    2    5
1    3    0
1    4    0
1    5    0
1    6    3
1    7    4
1    8    0
1    9    0
2    1    0
2    2    0
2    3    1
2    4    0
3    1    1
3    2    1
3    3    2

需求说明

  • 提取第三列值为0的连续行的首行与末行;
  • 若某行第三列为0且前后无同值行,需重复输出该行;
  • 按第一列分组处理:当第一列值变化时,即使第三列仍为0,也需视为新的0值区间。

期望输出

1    3    0
1    5    0
1    8    0
1    9    0
2    1    0
2    2    0
2    4    0
2    4    0

当前使用的awk脚本

awk '
function print_prev() {
   if (prevline) print prevline
   prevline=""
}
$3!=0 { print_prev() }
$3==0 { if (prev3!=$3) print
      prevline=$0
      }
      { prev3=$3 }
END   { print_prev() }
' test.txt

当前脚本输出

1    3    0
1    5    0
1    8    0
2    2    0
2    4    0
2    4    0

当前脚本未处理第一列分组逻辑,导致跨分组的0区间被错误合并,比如1 8 0到2 2 0被当成一个区间,未按分组拆分为两个独立区间输出首尾行。


修正后的awk脚本
awk '
# 输出当前0区间的首尾行,单一行则重复输出
function print_zero_range() {
    if (in_zero) {
        print startline
        # 首尾同一行则重复输出
        if (startline == currline) {
            print currline
        } else {
            print currline
        }
        in_zero = 0
    }
}

# 触发区间结束的情况:当前行第三列非0,或者第一列与上一行不同且处于0区间
$3 != 0 || ($1 != prev1 && in_zero) {
    print_zero_range()
}

# 处理0值行
$3 == 0 {
    # 若当前不在0区间,记录起始行
    if (!in_zero) {
        startline = $0
        in_zero = 1
    }
    # 更新当前行(区间末行)
    currline = $0
}

# 记录上一行的第一列值
{ prev1 = $1 }

# 处理文件末尾剩余的0区间
END {
    print_zero_range()
}
' test.txt

修正说明

  1. 新增prev1变量跟踪上一行的第一列值,用于判断分组变化;
  2. 用in_zero标记是否处于0值区间,startline记录区间首行,currline记录区间当前行(即末行);
  3. 当遇到非0值行,或者第一列变化且当前处于0区间时,调用print_zero_range输出区间首尾;
  4. 单一行的0区间会重复输出该行,满足需求;
  5. END块确保文件末尾的0区间被处理。

修正后输出

1    3    0
1    5    0
1    8    0
1    9    0
2    1    0
2    2    0
2    4    0
2    4    0

内容的提问来源于stack exchange,提问作者pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 12:53:16