从文件中删除三行直到匹配

从文件中删除三行直到匹配
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(包括)。我尝试了这个,但它不起作用:

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

答案1

使用sed理解相对地址的 a (非标准,但普遍支持):

$ 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以下两行(如果存在)并将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

在您的示例输入/输出中,以清除在记录的第三行而不是第一行错误匹配的脚本,或者对您的目标号码进行部分匹配而不是完全匹配。

答案4

使用(以前称为 Perl_6)

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

#OR

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

上面的代码使用 Raku 的fff“触发器”运算符,它检测以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变体,可以在返回中留下两个识别序列中的一个或两个。它们是^ffffff^^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连续的换行符进行拆分。然后代码的其余部分简化为以下内容,但不幸的是在文件的最后添加了两个空行:

~$ 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

相关内容