perl 从多个文件中删除所有以时间(HH:mm)开始并以特定字符串结尾的段落[已关闭]

ecfsfe2w  于 2023-01-26  发布在  Perl
关注(0)|答案(5)|浏览(122)
    • 已关闭**。此问题需要超过focused。当前不接受答案。
    • 想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

昨天关门了。
Improve this question
我需要从文件夹中的大量文件中删除以HH:mm格式的时间开头并以特定字符串结尾的任何段落/文本块。需要删除的每个段落都以字符串#file结尾。每个段落之间都有一个空行。是否可以删除这两个段落之间的所有内容?示例文件如下:

00:00  
-Paragraph one. Can be multiple  
lines. Paragraph one. Don't delete  
this paragraph. #No

19:30  
-Paragraph two.  
-Can be multiple lines.  
-Delete this paragraph. #file

13.30  
-Paragraph three. Delete this. #file

所以理想情况下剩下的是:

00:00  
-Paragraph one. Can be multiple  
lines. Paragraph one. Don't delete  
this paragraph. #No

这些段落永远不会是文档的第一段,但可能是最后一段。
我不是Maven,所以我一直在尝试的东西,我发现网上没有运气。感谢任何帮助,你可以给我!

编辑:
感谢大家的所有帮助。我最终得到了这个,因为它更接近我已经尝试过的,完美地为任何人寻找类似的东西:
gawk-i在原处'开始{RS = ORS ="\n\n "}!/#文件/'*. md

yfjy0ee7

yfjy0ee71#

在每个Unix机器上的任何shell中使用任何awk:

$ awk -v RS= -v ORS='\n\n' '!/#file$/' file
00:00
-Paragraph one. Can be multiple
lines. Paragraph one. Don't delete
this paragraph. #No
ntjbwcob

ntjbwcob2#

我将按照以下方式利用GNU AWK完成此任务,让file.txt内容

00:00
-Paragraph one. Can be multiple
lines. Paragraph one. Don't delete
this paragraph. #No

19:30
-Paragraph two.
-Can be multiple lines.
-Delete this paragraph. #file

13.30
-Paragraph three. Delete this. #file

那么

awk 'BEGIN{RS=""}!/#file/' file.txt

给出输出

00:00
-Paragraph one. Can be multiple
lines. Paragraph one. Don't delete
this paragraph. #No

说明:我将RS(行分隔符)设置为空字符串,这会触发段落模式,因此行被一个或多个空行分隔,然后我选择不(!)包含#file的行。如果要保留多个项目,则它们之间将没有空行,如果需要,请使用RS=ORS="\n\n"替换RS=""

  • (在GNU Awk 5.0.1中测试)*
w1jd8yoj

w1jd8yoj3#

这里有一个替代方案。不是100%清楚第一段的要求是什么,所以我无条件地打印了它。

#!/usr/bin/perl

use warnings;
use strict;

# set paragraph mode
local $/ = "";

# always print first paragraph
print scalar <DATA> ;

while (<DATA>)
{
    print 
        unless /^\d\d:\d\d.*#file\s*$/s;
}

__DATA__
01:01
keep this text even though it has #file

another paragraph with no data

01:00
delete this #file

07:057
delete this as well #file

keep this paragraph

02:33
keep me

运行将产生以下输出

01:01
keep this text even though it has #file

another paragraph with no data

keep this

02:33
keep me
y4ekin9u

y4ekin9u4#

这里有一个Perl的解决方案,因为你还没有向我们展示你尝试过什么,所以我不打算解释它是如何工作的,但是它是用Unix filter编写的。

#!/usr/bin/perl

use strict;
use warnings;

my $buffer;

while (<>) {
  if (/^\d\d:\d\d\s*$/) {
    end_of_para($buffer);

    $buffer = $_;
  } else {
    $buffer .= $_
  }
}

end_of_para($buffer);

sub end_of_para {
  my ($para) = @_;

  if ($para and $para !~ /#file\s*\z/) {
    print $para;
  }
}

**更新:**您已经更改了示例输入文件。这使事情变得简单得多。

#!/usr/bin/perl

use strict;
use warnings;

local $/ = '';

while (<>) {
  print unless /#file\s*\z/;
}
wmvff8tz

wmvff8tz5#

这可能对您有用(GNU sed):

sed -En '/^[0-9]{2}:[0-9]{2}/{:a;$!{N;/\n$/!ba};/#file\n?$/!p}' file

打开扩展正则表达式并关闭隐式打印。
将以HH:MM开头、以空行或文件结尾的行收集起来。如果最后一个字符串不是#file,则打印结果。
重复。

相关问题