【问题标题】:How can i remove multiple lines from a file based on a pattern that spans multiple lines?如何根据跨越多行的模式从文件中删除多行?
【发布时间】:2020-02-09 19:49:24
【问题描述】:

我的文本格式如下:

2020-05-02
apple
string
string
string
string
string
2020-05-03
pear
string
string
string
string
string
2020-05-03
apple
string
string
string
string
string

每个组都有7 lines = Date、Fruit 和 5 个字符串。

我想通过仅提供日期和水果来从文件中删除 7 行组。

所以如果选择'2020-05-03''pear'

这将删除:

2020-05-03
pear
string
string
string
string
string

从文件中得到:

2020-05-02
apple
string
string
string
string
string
2020-05-03
apple
string
string
string
string
string

该文件包含数千行,我需要一个命令,可能使用 sed 或 awk 来:

  1. 搜索日期2020-05-03

  2. 检查日期后的字符串是否为pear

  3. 删除这两行和后面的5

我知道我可以像sed s'/string//g' 这样使用 sed 删除,但是我不确定是否可以删除多行。

注意: 日期后跟水果从不重复两次 所以

2020-05-02
pear

只会在文件中出现一次

我怎样才能做到这一点?

【问题讨论】:

  • 听起来像2020-05-03\npear\n(?:.*\n){5}
  • 感谢@MonkeyZeus 我修复了它
  • sed s'/2020-05-03\npear\n(?:.*\n){5}//' 似乎不起作用,但不会抛出错误
  • 我不是 sed 专家,但也许它不支持非捕获组,所以试试2020-05-03\npear\n.*\n.*\n.*\n.*\n.*\n
  • 我认为问题是 \n ,它不匹配,例如: sed s'/2020-05-03\npear//' 不删除前两行

标签: regex bash awk sed


【解决方案1】:

使用awk, 你可以这样做:

awk -v dt='2020-05-03' -v ft='pear' '$1==dt{p=NR} p && NR==p+1{del=($1==ft)}
del && NR<=p+6{next} 1' file

2020-05-02
apple
string
string
string
string
string
2020-05-03
apple
string
string
string
string
string

说明:

  • -v dt='2020-05-03' -v ft='pear':从命令行向 awk 提供 2 个值
  • $1==dt{p=NR}:如果我们找到匹配日期的行,则将行号存储在变量 p
  • p &amp;&amp; NR==p+1{del=($1==ft)}:如果 p&gt;0 并且我们在下一行,则将标志 del 设置为 1,如果我们有匹配的水果名称,则将该标志设置为 0
  • del &amp;&amp; NR&lt;=p+6{next}:如果设置了标志 del,则跳过接下来的 6 行
  • 1:打印行的默认操作

【讨论】:

    【解决方案2】:

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

    sed '/2020-05-03/{:a;N;s/[^\n]*/&/7;Ta;/^[^\n]*\npear/d}' file
    

    如果一行包含2020-05-03,则总共收集7行,如果这些行中的第二行包含pear,则删除它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 2016-05-31
      • 2021-04-14
      • 2022-10-14
      • 2017-02-20
      • 2017-06-06
      • 2012-12-15
      相关资源
      最近更新 更多