Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在perl中,从文件中删除特定行_Perl - Fatal编程技术网

在perl中,从文件中删除特定行

在perl中,从文件中删除特定行,perl,Perl,我要删除带有HPOM的行,并仅保留行节点: 我的代码: #!/usr/bin/perl use strict; open (FILE, "/tmp/agentstas.dat"); my @lines = <FILE>; my $lines; my $string = "Node"; my $badstring = "hpom"; foreach $lines (@lines) { if ($lines =~ $string || $lines !=~ $bad

我要删除带有HPOM的行,并仅保留行节点:

我的代码:

#!/usr/bin/perl
use strict;

open (FILE, "/tmp/agentstas.dat");

my @lines = <FILE>;

my $lines;

my $string = "Node";

my $badstring = "hpom";

foreach $lines (@lines) {

    if ($lines =~ $string || $lines !=~ $badstring)  { print "$lines"; }

}

始终使用三个参数和词法文件句柄执行文件操作。
如果要删除从“HPOM”开始的所有行,可以将代码编写为:

open my $fh, "<", "/tmp/agentstas.dat" or die $!;

my @lines = <$fh>;

foreach my $lines (@lines)
{
    next if ($lines =~ m/^HPOM/i);
    print "$lines";
}
或者在代码中更改此行:

if ($lines =~ $string || $lines !=~ $badstring)  { print "$lines"; }

^
=匹配字符串的开头。
i
=进行不区分大小写的模式匹配


i
因为您使用的是小写字母的
$badstring
,而在输入文件中它是大写字母的。

您的初始代码太复杂了。请尝试以下方法:

#!/usr/bin/env perl

use strict;
use warnings; 

open (my $input, '<', "/tmp/agentstas.dat") or die $!;

while ( <$input> ) {
   print if m/^Node/i;
}
close ( $input );
#/usr/bin/env perl
严格使用;
使用警告;

打开(my$input,“硬编码文件名通常是个坏主意。如果使用Unix筛选器模型(从STDIN读取,写入STDOUT),程序会更灵活

!/usr/bin/perl
而(){
打印,除非/^HPOM/;
}
按以下方式运行:

$ ./your_filter.pl < /tmp/agentstas.dat > output_file
$。/your_filter.pl输出文件

您的思路是正确的。错误处于
if
状态

if ($lines =~ $string || $lines !=~ $badstring)
应该是

if ($lines =~ $string && $lines !=~ $badstring)
因为您希望两个条件都为真(AND、not或)

使用perl的
-n
开关,我们可以很好地解决这个问题:

$ perl -ne '/Node/ && ! /hpom/ && print' /tmp/agentstas.dat
您甚至不必使用perl,只需使用

$ grep -e ^Node /tmp/agentstas.dat

仅列出以“Node”开头的行(这似乎是您试图实现的)。

您已在问题中添加了第二个问题。请不要-提问是免费的,请单独提问。(这不会使现有答案无效)。我已回滚到大规模重新编辑之前的版本。请接受下面的一个答案,以防止此问题显示为未解决,如果您需要其他问题的帮助,请发布新问题。(如果上下文有意义,请在此提供链接。)也许还可以解释为什么
循环要好得多——它一次只在内存中保留一行,而不是将整个文件读入内存,然后慢慢地将其输出。如果您只想在
打印()中添加换行符,为什么
chomp()
?刚刚演示,以防OP将执行其他操作而不是直接打印。虽然技术上有效,但有标量
$lines
和数组
@lines
,特别是当
$lines
仅包含一行时,我想他甚至可以执行类似
映射{print,除非/^HPOM/}
那么,如果他想要一行:-)在void上下文中使用
map
不是一个好主意。也许您想要
打印grep{!/^HPOM/}
:-)
if ($lines =~ $string || $lines !=~ $badstring)
if ($lines =~ $string && $lines !=~ $badstring)
$ perl -ne '/Node/ && ! /hpom/ && print' /tmp/agentstas.dat
$ grep -e ^Node /tmp/agentstas.dat