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

如何用sed结合正则AND/OR条件删除test1上方的指定行?

嘿,我来帮你搞定这个sed的难题!你需要删除test1上方的行,条件是那行要么不含test1,要么不以引号结尾——这个需求核心是要处理行上下文(关联当前行和它的前一行),sed的保持空间(hold space)正好能帮我们做到这一点。

需求拆解

先明确逻辑:对于每一行包含test1的行,我们要检查它的前一行:

  • 如果前一行「不包含test1」或者「不以引号结尾」→ 删除前一行,只保留test1所在行
  • 如果前一行「既包含test1又以引号结尾」→ 同时保留前一行和test1所在行

解决方案:用sed保持空间处理上下文

这里有两个版本,一个是逻辑清晰的分步版,一个是简化版,你可以按需选择:

版本1:逻辑清晰的分步实现

sed -n '
  # 第一行直接存入保持空间,无前置行可处理
  1h
  # 从第二行开始处理每一行
  1!{
    # 将当前行追加到保持空间,此时保持空间是「前一行\n当前行」
    H
    # 交换保持空间和模式空间,现在模式空间里存着两行内容
    x
    # 检查当前行(模式空间第二行)是否包含test1
    /test1/{
      # 先判断前一行是否不含test1
      /^\(.*test1.*\)$/!{
        # 去掉前一行,只输出当前行
        s/.*\n//p
        b
      }
      # 前一行包含test1,再判断是否以引号结尾
      /"$/{
        # 两行都符合保留条件,输出整段
        p
        b
      }
      # 前一行包含test1但不以引号结尾,只输出当前行
      s/.*\n//p
      b
    }
    # 当前行不含test1,输出前一行,再把当前行存入保持空间
    s/\n.*//p
    s/.*\n//h
  }
  # 处理最后一行:如果最后一行不含test1,输出它
  ${/test1/!p}
' your_file.txt

版本2:用正则OR条件简化

我们可以把「不包含test1 或者 不以引号结尾」转化为「不满足(包含test1 且 以引号结尾)」,用一个正则就能搞定,命令更简洁:

sed -n '
  1h
  1!{
    H;x
    # 当当前行包含test1时
    /test1/{
      # 如果前一行不满足「包含test1且以"结尾」,就去掉前一行
      /^\(.*test1.*"$\)/!s/.*\n//
      # 输出处理后的内容
      p
    }!{
      # 当前行不含test1,输出前一行并更新保持空间
      s/\n.*//p
      s/.*\n//h
    }
  }
  ${/test1/!p}
' your_file.txt

关键细节说明

  • -n:让sed默认不输出任何行,我们手动控制哪些行需要输出,避免多余内容
  • 保持空间(h/H/x命令):用来暂存前一行的内容,实现行与行之间的关联处理
  • 正则部分:如果你的引号是单引号,只需要把命令里的"换成'即可(注意sed中单引号的转义,GNU sed可以用\',或者用'\''来嵌套)

测试示例

假设你的输入文本是:

line1 no test1, ends with "
line2 has test1, ends with "
test1 line3
line4 no test1, no quote
test1 line5
line6 has test1, no quote
test1 line7

运行命令后会得到:

line2 has test1, ends with "
test1 line3
test1 line5
test1 line7

完全符合你的需求:删除了不符合条件的前置行,保留了符合条件的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:12:12