Perl - 如何从文本文件中省略行?
Posted
技术标签:
【中文标题】Perl - 如何从文本文件中省略行?【英文标题】:Perl - How to omit lines from a text file? 【发布时间】:2021-06-20 13:14:05 【问题描述】:我有一个文本文件,我希望从文本文件中省略一些行,并使用该字符串创建一个新文件。好消息是我的文本文件以包含“START”并以“END”结尾的行开头我需要的文本块。
例如,我的文本文件如下所示:
1
2
3
Start
4
5
6
End
7
8
Start
9
10
End
所需的输出是两个字符串,我可以将它们输出到如下所示的文本文件中:
Start
4
5
6
End
Start
9
10
End
我目前拥有的:
open(RH, '<', $fileName) or die $!;
while(<RH>)
#print $_;
chomp $_;
if ($_ eq 'START')
$str = "$str"."$_\n";
但我不确定如何继续。
编辑: 我使用以下方法回答了这个问题:
$cmd = q(awk '/Start/,/End/ print' foo.txt);
my $output = qx($cmd);
my @cards = split (/(?<=\End)/, $output);
【问题讨论】:
【参考方案1】:您可以从 AWK 中使用 Perl 的一些遗产,然后执行此操作(假设您的文件名为 foo.txt)
perl -ne'print if /Start/../End/' foo.txt
表达式/Start/../End/
的意思是“从匹配/Start/
的第一行到匹配/End/
的下一行。
awk 的等效代码是
awk '/Start/,/End/ print' foo.txt
【讨论】:
如果我想在我的 perl 脚本中使用这些行,我将如何使用它? @NelsonSwasono 在另一篇与here 主题几乎相同的帖子中得到了回答。我不确定你为什么在说“谢谢”之后删除了该主题——通常,你会 accept the answer 并让它成为未来与你有同样问题的访问者的资源。考虑对这个线程和你提出的其他问题做同样的事情。【参考方案2】:# Read the entire file into a string `$str`:
open my $fh, '<', 'file_name' or die "Can't open file $!";
my $str = do local $/; <$fh> ;
close $fh;
while ($str =~ m\n(START\n.*\nEND)\nmsg)
# Do something with each START...END set of lines
print "$str\n";
注意事项:
我不确定所有细节。local $/
;可能由 undef $/;
之类的东西完成
调整括号以避免捕获“START”和“END”。
【讨论】:
$/ = undef;
比 undef $/;
好,local $/;
是本地化后最好的。
不确定这是否正常工作。我假设您的代码示例打印出我想要的输出,但不幸的是,没有任何东西打印到终端。在 while 循环之前,文本文件被正确加载到 $str 中,但 while 循环不能正常运行。
@NelsonSwasono - 我对何时使用 /m 和 /s 感到困惑——删除任何一个。
不幸的是,这仍然不起作用,您的示例中没有 /m 或 /s
@NelsonSwasono - TIMTOWTDI -- 我喜欢说=~ m...
而不是=~ /.../
。这导致=~ m...msg
而不是=~ /.../msg
。【参考方案3】:
使用 GNU grep
:
grep -Poz '(?ms)^Start.*?^End\n' in_file
这里,GNU grep
使用以下选项:-P
:使用 Perl 正则表达式。-o
:仅打印匹配项(每行 1 个匹配项),而不是整行。-z
:将输入和输出数据视为行序列,每行都以零字节(ASCII NUL 字符)而不是换行符结尾。因此,您可以匹配输入中的换行符。
(?ms)
:分别启用m
和s
pattern-match modifiers 以允许多行匹配,并允许.
匹配换行符。
另请参阅:grep
manualperlre - Perl regular expressions
【讨论】:
【参考方案4】:使用..
作为“触发器”运算符。
# Switch to a lexical filehandle
# (as this is modern best practice)
open(my $rh, '<', $fileName) or die $!;
# Open an output filehandle
my $x = 1;
open my $out, '>', "$filename.out.$x" or die $!;
while(<$rh>)
print $out $_ if /Start/ .. /End/;
# Open a new output file if we've seen 'End'
if (/End/)
++$x;
open my $out, '>', "$filename.out.$x" or die $!;
【讨论】:
以上是关于Perl - 如何从文本文件中省略行?的主要内容,如果未能解决你的问题,请参考以下文章