BASH:如果行匹配 - 删除行+接下来的33行

时间:2012-01-06 05:02:35

标签: regex perl bash sed awk

我有一个充满记录的文件......每条记录长34行。

我需要清除第一行记录与字符串匹配的任何记录的此文件。 第一行是位置代码。必须清除文件来自特定位置的所有记录。在每条记录的第一行之后有一个空行...实际上有几行,但是,任何出现空行都表示该记录属于该位置。

所以 -

如果行匹配 而下一行是空白的 然后删除行后的行+33行。

更喜欢bash解决方案,因为这是我最熟悉的,但perl还可以。

有些人要求提供样本(此记录在现实生活中为34行):

LOCATION



DARRYL MITHRANDIR
5 LONGBOTTOM LEAF LN
HOBBITON, ME  99999

We rang to notify you that we have the following items:

1 blade - glamdring = $1,000
1 shrunken troll head = $1

Available for pick-up at the following location:

LOCATION
8 SMAUG LN
MORDOR, ME  99998

如您所见,位置始终作为记录中的第一行,后跟一系列空行。它出现在记录的其他地方,但后面跟着一行表示街道地址的文本。

3 个答案:

答案 0 :(得分:4)

嗯,这是awk的回答。将LOCATION更改为适合您的匹配的正则表达式。

  awk '/LOCATION/{l=$0;getline;if(!$0)i=33; else print l}i{if(--i);next}1'

基于您的示例

$ cat ./input
LOCATION  ### DELETE THIS RECORD ###



DARRYL MITHRANDIR
5 LONGBOTTOM LEAF LN
HOBBITON, ME  99999

We rang to notify you that we have the following items:

1 blade - glamdring = $1,000
1 shrunken troll head = $1

Available for pick-up at the following location:

CHUCKS AMAZING BARGAINS
8 SMAUG LN
MORDOR, ME  99998
LOCATION  ### DONT DELETE THIS RECORD, NEXT LINE NOT BLANK ###
FOO BAR
31337 EXAMPLE WAY
EXAMPLETON, EX  12345

We rang to notify you that we have the following items:

1 ring of awkfu = $99,000,000
1 troll face = jelly?

Available for pick-up at the following location:

SIEGEXS AMAZING EXAMPLES
314159 PI CIRCLE
NOWHERE, NA 00000

使用您的17行/记录示例输出

$ awk '/LOCATION/{l=$0;getline;if(!$0)i=17; else print l}i{if(--i);next}1' ./input
LOCATION  ### DONT DELETE THIS RECORD, NEXT LINE NOT BLANK ###
FOO BAR
31337 EXAMPLE WAY
EXAMPLETON, EX  12345

We rang to notify you that we have the following items:

1 ring of awkfu = $99,000,000
1 troll face = jelly?

Available for pick-up at the following location:

SIEGEXS AMAZING EXAMPLES
314159 PI CIRCLE
NOWHERE, NA 00000

答案 1 :(得分:2)

这可能对您有用:

sed -i '/LOCATION/{N;/\n$/{:a;N;x;s/^/X/;/^X\{32\}/{g;d};x;ba}}' file

根据说明:

  

如果行匹配且下一行为空,则删除行后的行+33行。

说明:

  • (1)在LOCATION
  • 上匹配
  • 如果(1)以上
    • 追加下一行N
    • (2)将模式空间(PS)的最后一个字符与换行符(即空行)匹配。
      • 如果上述(2)
        • 创建标签:a
        • 添加换行符,然后将下一行添加到(PS)N
        • 将PS与保留空间(HS另一个寄存器)x
        • 交换
        • X附加到HS s/^/X/
        • 的正面
        • (3)将HS与32 X的{​​{1}}匹配
          • 如果上述(3)
            • 将PS复制到HS /^X\{32\}/
            • 删除HS并开始下一个周期g
          • 否则
            • 从HS换回PS d
            • 转到标签x

答案 2 :(得分:1)

您可以使用awk -

执行此类操作
awk '/YOUR PATTERN/ {
i=$0;getline; if($0~/^$/)
for(i=1;i<34;i++) {getline} else {print i,$0;next}}1' file

说明:

  1. 我们会查找包含您的模式的行。
  2. 如果我们找到它,我们将整行存储在变量i中。
  3. 然后,我们使用getline关键字检查下一行,如果是blank line我们向下移动33次。
  4. 如果下一行不是空白行,我们会打印出变量i
  5. 最后的1用于打印与图案不匹配的所有行。
相关问题