【问题标题】:delete lines if firstline matches expression, but next 2 lines do not match different expression如果第一行匹配表达式,则删除行,但接下来的 2 行不匹配不同的表达式
【发布时间】:2023-03-26 02:58:01
【问题描述】:

我有一个这种格式的测试文件:

G03X22Y22.5
G01X48.5
M98P9001 (OFF)****
G00X20Y25
M98P8051 (FAST CUT)
G01X22Y34
G01X25Y33

我正在尝试制作一个 bash 或 MSDOS 脚本:

查找文件中所有匹配的行:M98P9001

如果 NEXT 2 LINES 不包含代码 { M98P8050, M98P8080 OR M09 } 删除所有 3 行。这将导致输出:

G03X22Y22.5
G01X48.5
G01X22Y34
G01X25Y33

我尝试过使用 SED 或 AWK 的解决方案,但还没有找到合适的解决方案:

sed -e '/M98P9001/,+2d' input.txt >> output.txt

找到匹配项后,此行将始终删除所有 3 行,但如果匹配项后的下 2 行与 { M98P8050, M98P8080 OR M09 } 不匹配,我只需要删除这些行。

【问题讨论】:

  • M98P90012345 是否“匹配”M98P9001?类似地,您要匹配的所有字符串 - 您是在寻找部分匹配还是完整工作匹配或其他内容?
  • 后续的两行必须匹配还是只有其中之一?

标签: bash awk sed


【解决方案1】:

标记和扫描方法

$ awk 'NR==FNR {if(!(/M98P80[58]0|M09/ && p~/M98P80[58]0|M09/) && pp~/M98P9001/)
                 {a[NR]; a[NR-1]; a[NR-2]} 
                pp=p; p=$0; next} 
       !(FNR in a)' file{,}


G03X22Y22.5
G01X48.5
G01X22Y34
G01X25Y33

【讨论】:

  • 从问题中不清楚M09是否应该匹配M09P123
【解决方案2】:

这似乎给出了你想要的输出:

awk '
  /M98P9001/ { 
    getline l2; getline l3;
    if((l2 l3)~/M98P8050|M98P8080|M09/) printf "%s\n%s\n%s\n", $0, l2, l3; 
    next; 
  } 
  { print; }'

说明:

  • 如果第一行模式匹配,则将下两行读入变量。
  • 检查两行的串联是否有 3 个辅助模式中的任何一个
  • 如果匹配,则打印所有三行,否则不打印。
  • 转到下一条记录。
  • 在所有其他行上打印。

【讨论】:

    【解决方案3】:

    这可能对你有用(GNU sed):

    sed -E ':a;N;s/\n/&/2;Ta;/^[^\n]*M98P9001/{/\n.*(M98P8050|M98P8080|M09)/!d};P;D' file
    

    在整个文件中打开一个三行窗口。

    如果窗口的第一行包含M98P9001,而第二行或第三行中的任何一个都不包含M98P8050M98P8080M09,则删除整个窗口并重复。

    否则,打印/删除窗口的第一行并重复。

    注意成语:a;N;s/\n/&/2;Ta 将三行窗口置顶。

    【讨论】:

      猜你喜欢
      • 2013-03-22
      • 1970-01-01
      • 2022-12-11
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多