最初の一致を含む行の下のn行にあるすべての行を削除します。

最初の一致を含む行の下のn行にあるすべての行を削除します。

ファイルに次の内容が含まれている場合:

Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7
Line 5
Line 8
Line 9

これで、ファイルに次の内容のみが含まれるように、「5行目」の2行下の行を削除するにはどうすればよいですか?

Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7

注:これは質問のわずかに改善された反転バージョンです。最初の一致を含む行の上のn行前のすべての行を削除します。

答え1

そしてsed

$ sed '/^Line 5$/{n;n;q;}' file
Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7

ファイルを適切に編集するには、-iGNUsedまたは互換バージョン、-i ''FreeBSD sed、または互換バージョンオプションを追加します。

答え2

awkを使用してください。

$ awk -v n=2 'c&&!--c{exit} $0 == "Line 5"{c=n+1} 1' file
Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7

バラよりsed-or-awk-a-line-following-a-matching-patternを使用した印刷/17914105#17914105説明と関連慣用語を表示するには

答え3

以下はいくつかの方法です。どちらも、正しい文字列を含む行の後の2行だけを削除し始めるとしますLine 5

  • 真珠

    $ perl -lne '$k=$. if /^Line 5$/; print; exit if $k and $.==$k+2;' file
    Line 1
    FooLine 5
    Line 2
    Line 55
    Line 3
    Line 4
    Line 5
    Line 6
    Line 7
    

    perl -i -lne '$k=$. if /^Line 5$/; print; exit if $k and $.==$k+2;' fileこれを使用してファイルを所定の位置に編集できます。

  • awk

    awk '(/^Line 5$/){ k=NR } 1; (k && NR==k+2){exit};' file
    Line 1
    FooLine 5
    Line 2
    Line 55
    Line 3
    Line 4
    Line 5
    Line 6
    Line 7
    

答え4

使用幸せ(以前のPerl_6)

~$ raku -pe 'if m/^Line \h 5$/ {.put; get.put xx 2; last};'  file

または:

~$ raku -pe 'm/^Line \h 5$/ && .put && get.put xx 2 && last;'  file 

または:

~$ raku -ne 'm/^Line \h 5$/ ?? (.put; get.put xx 2; last) !! .put;'  file

以下は、Perlシリーズのプログラミング言語であるRakuで書いた答えです。 RakuにはUnicodeの高度なサポート機能が組み込まれています。

最初の回答ペアでは、-pe1行ずつ自動印刷フラグを使用します。必要な行が読み取られるまで(正規表現で決定される)、行は自動的に印刷されます。この時点で必要な行は out でput、コードはget他の 2 行を指示してout配置します。それはすべてですlast(つまり、コードが終了します)。これら2つの例のうちの2番目のケースでは、代わりにandthen使用できます&&

3番目の答えでは、-ne自動印刷ではなく1行ずつフラグを使用してください。各行はRakuのものとして読み込まれます。テスト ?? 本物 !! 間違った三項演算子は正規表現で目的の行を探します。目的の動作がTrueの場合、outの場合、putコードはgetさらに2行を指示し、outそれを入力すると終了ですlast(つまり、コードは終了します)。正規表現を介して希望の動作がFalseの場合は直接出力し、1行putずつ、可能であればファイルの最後まで読み続けます。

入力例:

Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7
Line 5
Line 8
Line 9

出力例:

Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7

get.put注:上記の3つの答えすべて、空の行はうまく処理されますが、存在しない行を返そうとすると(たとえば、ファイルの末尾に近すぎると)コードでエラーが発生します。エラー。

これをよりエレガントに処理するには(一致する行の後に利用可能なすべての行を要求された数まで返す)、@terdonのPerlの回答に似た次のコードを使用します。以下を$k「」と同じに設定してください。n+1「lines は現在の行にプラスを返します」N- 次の行($k=3上記と同じ出力を提供):

~$ raku -ne 'my $k=3 if m/^Line \h 5$/; $k.put && --$k; last unless $k;'  file

https://docs.raku.org
https://raku.org

関連情報