删除之前和之后在bash匹配的行(与SED或AWK)?(Delete lines before an

2019-09-20 17:43发布

我试图删除两行从完整的交易文件中的模式匹配的两侧。 IE浏览器。 然后找到匹配删除两条线前,然后后删除两行,然后删除了比赛。 写这回原来的文件。

因此,输入数据是

D28/10/2011
T-3.48
PINITIAL BALANCE
M
^

和我的模式是

sed -i '/PINITIAL BALANCE/,+2d' test.txt

然而,这仅删除模式匹配后两行,然后删除模式匹配。 我不能工作了使用SED由原来的文件全部删除5行数据的任何逻辑方式。

Answer 1:

SED将做到这一点:

sed '/\n/!N;/\n.*\n/!N;/\n.*\n.*PINITIAL BALANCE/{$d;N;N;d};P;D'

它的工作原理下一方式:

  • 如果sed的有且只有一个模式空间字符串它加入一个又一个
  • 如果只有两个它加入第三个
  • 如果它natch图案线+线+符合平衡它连接两个下列字符串,删除这些文件并在开始时变为
  • 如果不是,它的图案印刷第一串和其删除,并在一开始不用刷卡模式空间

防止格局appearence的第一个字符串你应该修改脚本:

sed '1{/PINITIAL BALANCE/{N;N;d}};/\n/!N;/\n.*\n/!N;/\n.*\n.*PINITIAL BALANCE/{$d;N;N;d};P;D'

然而,万一失败,你有另一个PINITIAL BALANCE中的字符串,将要被删除。 但是其他的解决方案也失败=)



Answer 2:

一个awk一个班轮可以做的工作:

awk '/PINITIAL BALANCE/{for(x=NR-2;x<=NR+2;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file

测试:

kent$  cat file
######
foo
D28/10/2011
T-3.48
PINITIAL BALANCE
M
x
bar
######
this line will be kept
here
comes
PINITIAL BALANCE
again
blah
this line will be kept too
########

kent$  awk '/PINITIAL BALANCE/{for(x=NR-2;x<=NR+2;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file
######
foo
bar
######
this line will be kept
this line will be kept too
########

添加一些说明

  awk '/PINITIAL BALANCE/{for(x=NR-2;x<=NR+2;x++)d[x];}   #if match found, add the line and +- 2 lines' line number in an array "d"
      {a[NR]=$0} # save all lines in an array with line number as index
      END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' #finally print only those index not in array "d"
     file  # your input file


Answer 3:

对于这样的任务,我可能会达到如Perl更先进的工具:

perl -ne 'push @x, $_;
          if (@x > 4) {
              if ($x[2] =~ /PINITIAL BALANCE/) { undef @x }
                  else { print shift @x }
          }
          } END { print @x'


Answer 4:

这可能会为你工作(GNU SED):

sed ':a;$q;N;s/\n/&/2;Ta;/\nPINITIAL BALANCE$/!{P;D};$q;N;$q;N;d' file


Answer 5:

这段代码保存到一个文件grep.sed

H
s:.*::
x
s:^\n::
:r
/PINITIAL BALANCE/ {
    N
    N
    d    
}

/.*\n.*\n/ {
    P
    D
}
x
d

并运行如下命令:

`sed -i -f grep.sed FILE`

你可以这样无论是使用它:

sed -i 'H;s:.*::;x;s:^\n::;:r;/PINITIAL BALANCE/{N;N;d;};/.*\n.*\n/{P;D;};x;d' FILE


文章来源: Delete lines before and after a match in bash (with sed or awk)?
标签: shell sed awk