(パターン範囲内)文字列の最初の7項目に対応する行を削除します。

(パターン範囲内)文字列の最初の7項目に対応する行を削除します。

txtファイルのパターン範囲(string1-string2)から、文字列の最初の7項目に対応する行を削除する必要があります。

txtファイルコンテンツの例:

whatever
xpto string1 foo2
whatever1 
string2
xpto1 another_foo
xpto string2

string2 foo1

whatever
string2 another_xpto
string2 string2
foo xpto string2 whatever 
anything else foo string2
xpto
string2
foo whatever

次のsed範囲のソリューションが必要です。

sed '/string1/,/string2/d' ファイル.txt

/string2/要点は、string2の7番目の一致に対応する行に展開する方法がわからないことです。理想的な出力は次のようになります。

whatever
anything else foo string2
xpto
string2
foo whatever

答え1

sed -e:t -e'/string1/!b' -e'/\(.*string2\)\{7\}/d;N;bt'

答え2

awk '/string1/{c=7}; c<1; {c-=gsub(/string2/, "&")}' file

cstring1最初は0で、見つかった場合は7に設定されます。この行は毎回印刷されますc<1

この関数はgsub各行の発生回数を返します。string2カウンタはcこの値だけ減少します。

答え3

リテラル文字列を使用して目的の操作を実行する1つの方法は次のとおりです。

$ cat tst.awk
BEGIN { lgth = length(end) }
index($0,beg) { inBlock = 1 }
inBlock {
    rec = $0
    while ( pos = index(rec,end) ) {
        if ( ++cnt >= min ) {
            inBlock = 0
        }
        rec = substr(rec,pos+lgth)
    }
    next
}
{ print }

$ awk -v beg='string1' -v end='string2' -v min=7 -f tst.awk file
whatever
anything else foo string2
xpto
string2
foo whatever

上記では、文字列のバックスラッシュ(\tタブなど)について説明します。問題が発生した場合は簡単に解決できるので、教えてくださいENVIRON[]

答え4

真珠

perl -ne '
  if (my $e = /string1/ ... s/string2/$&/g >= 7) {
      $_ .= $e =~ /E0/ ? next : <>, redo;
  }
  print;
' file

POSIX sed:

sed -ne '
  /string1/!{p;d;}
  :loop
    n
    /string2/H
    g;s//&/7;t
  b loop
' file

出力:

whatever
anything else foo string2
xpto
string2
foo whatever

関連情報