一致するまでファイルから3行を削除します。

一致するまでファイルから3行を削除します。
982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

984
01:25:15,390 --> 01:25:18,484
( MAJESTIC MUSIC )

984次の3行(含む)を削除したいと思います。私はこれを試しましたが、うまくいきません。

perl -0777 -pe 's/.*\n.*\n\(.*\)//'

答え1

相対アドレスを理解するためにaを使用してくださいsed(非標準ですが、一般的にサポートされています)。

$ sed '/^984$/,+2d' input_file
982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

または以下を使用してsed

sed '/^984$/{$!N;$!N;d;}' input_file

つまり、一致にN次の2行(存在する場合)を追加し、d両方を削除します。

答え2

このように:

短絡モードで:

$ perl -00 -ne 'print unless /^984\b/' file

一行ずつ:

$ perl -anE 'if ($F[0] == 984) { last } else { print }' file

正規表現を使用してファイル全体を解析します。

$ perl -0777 -ne 'print $& if /.*(?=\n^984)/ms' file
$ perl -gne 'print $& if /.*(?=\n^984)/ms' file # perl >= 5.36

出力

983
01:25:09,473 --> 01:25:10,978
Stay with me.

1 正規表現マッチングは次のとおりです。

正規表現 説明する
.* 0個以上の文字と一致します。
(?= 肯定的な配信の主張
\n 改行文字の一致
^ 文字列の先頭に一致します。
984) 4つの文字を一致させ、984プレビューをオフにします。

答え3

RS=<null>ショートモードでawkを使用する(入力レコードが空白行で区切られたときに有効および使用されます):

$ awk -v RS= -v ORS='\n\n' '$1 != 984' file
982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

何らかの理由で段落モードを使用できない場合(たとえば、レコード間の空白行に実際には見えない印刷できない文字が含まれています)、その時点で始まる4行を削除したい場合は984、あります。これは(しかしそれほど頑丈ではありません。以下を参照してください):

$ awk '$1 == "984"{c=4} !(c&&c--)' file
982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

バラより印刷には sed- または awk-a-line-follow-a-matching-pattern を使用します。関連awkイディオム。

最初のスクリプトは、最初の空白行の後の984にのみ一致するため、最も強力です。次の状況を含める必要があります。

950
01:25:09,473 --> 01:25:10,984
this is bad

951
01:25:09,473 --> 01:25:10,978
984 here is also bad

9841
01:25:09,473 --> 01:25:10,978
this is also bad

入力/出力の例では、レコードの最初の行ではなく3行目で誤って一致するスクリプトをクリーンアップするか、ターゲット番号で正確に一致するのではなく部分一致を実行します。

答え4

使用幸せ(以前のPerl_6)

~$ raku -ne '.put unless /^ 984 $/ fff *.chars == 0 ;'  file

#OR

~$ raku -ne '.put unless /^ 984 $/ fff {.chars == 0} ;'  file

上記のコードは、空行(ゼロに等しい)で始まり、終了するレコードをfff検出するRakuの「トリガー」演算子を使用します。上記のコードは空行を検出しようとしません。984.chars今後 984

入力例:

982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

984
01:25:15,390 --> 01:25:18,484
( MAJESTIC MUSIC )

985
01:25:18,485 --> 01:25:18,500
( END CREDITS )

出力例(1):

982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

985
01:25:18,485 --> 01:25:18,500
( END CREDITS )

Rakuは、fff戻り時に2つの識別シーケンスの一方または両方を残すさまざまなバリエーションを提供します。それらは^fffまたはfff^またはです^fff^。これにより、プレビュー/戻りを使用する必要性が減ります。たとえば、fff上記のコードを次のように変更すると、^fff^次のような結果が得られます。

出力例(2):

982
01:25:09,473 --> 01:25:10,978
Stay with me.

983
01:25:09,473 --> 01:25:10,978
Stay with me.

984

985
01:25:18,485 --> 01:25:18,500
( END CREDITS )

最初にレコードを分割したい場合、または必要な場合は、slurpファイルを一度にマージして、連続\n\nした改行文字に簡単に分割します。残りのコードは次のように単純化されますが、残念ながら、ファイルの末尾に2つの空行が追加されます。

~$ raku -e 'for slurp.split("\n\n") { put $_ ~ "\n"  unless /^984 / };' file

心配しないでください。 Rakuを使用してファイルの先頭/末尾から空白行を削除するには、以下の最初のリンクを参照してください。

https://unix.stackexchange.com/a/725227/227738
https://docs.raku.org
https://raku.org

関連情報