我有一个重复行的大文件如下:
@UUSM
ABCDEADARFA
+------qqq
!2wqeqs6777
我想输出文件中的所有“第二行”。我执行此操作时会剪切以下代码,但它没有按预期工作。第1,3和4行代替输出。
open(IN,"<", "file1.txt") || die "cannot open input file:$!";
while (<IN>) {
$line = $line . $_;
if ($line =~ /^\@/) {
<IN>;
#next;
my $line = $line;
}
}
print "$line";
请帮忙!
答案 0 :(得分:1)
试试这个
open(IN,"<", "file1.txt") || die "cannot open input file:$!";
my $lines = "";
while (<IN>) {
if ($. % 4 == 2) $lines .= $_;
}
print "$lines";
答案 1 :(得分:1)
perl -ne '$at = $. if /^\@/; print if $. - 1 == $at' file1.txt
写出来,上面相当于
open my $fh, "<", "file1.txt";
my $at_line = 0;
while (<$fh>) {
if (/^\@/) {
$at_line = $.;
}
else {
print if $. - 1 == $at_line;
}
}
答案 2 :(得分:1)
我假设您要问的是如何打印以@
开头的行之后的行:
perl -ne 'if (/^\@/) { print scalar <> }' file1.txt
这说,“如果该行以@
开头,则打印下一行。对参数列表中的所有文件执行此操作。”这里使用scalar
函数在文件句柄上施加标量上下文,这样它就不会打印整个文件。默认情况下,print
具有其参数的列表上下文。
如果你真的想在文件中打印第二行,那就更容易了。以下是一些例子:
使用行号$.
变量,如果它等于第2行,则打印。
perl -ne '$. == 2 and print, close ARGV' yourfile.txt
请注意,如果您有多个文件,则必须关闭ARGV文件句柄才能重置计数器$.
。另请注意,使用较低优先级运算符and
会强制print
和close
都绑定到条件。
使用常规逻辑。
perl -ne 'print scalar <>; close ARGV;'
perl -pe '$_ = <>; close ARGV;'
在打印第二行时,通过关闭ARGV文件句柄,这两个都使用了短路功能。如果您想要打印文件的每隔一行,如果您删除close
语句,这两个行都会这样做。
答案 3 :(得分:0)
如果你想要打印第2,6,10行,那么:
while (<>)
{
print if $. % 4 == 2;
}
$.
是当前行号 - 我没有花时间打开和关闭文件。那可能是:
{
my $file = "file1.txt";
open my $in, "<", $file or die "cannot open input file $file: $!";
while (<$in>)
{
print if $. % 4 == 2;
}
}
这使用现代首选形式的文件句柄(词法文件句柄),构造周围的大括号意味着文件句柄自动关闭。无法打开的文件的名称包含在错误消息中;使用or
运算符,因此优先级正确(原语中的括号和||
也很好,可以在这里使用,但通常不是)。
如果您希望打印以@
开头的行后的行,则必须采用不同的方式组织。
my $print_next = 0;
while (<>)
{
if ($print_next)
{
print $_;
$print_next = 0;
}
elsif (m/^@/)
{
$print_next = 1;
}
}
问题中代码的原始版本是(为方便起见添加了行号):
1 open(IN,"<", "file1.txt") || die "cannot open input file:$!";
2 while (<IN>) {
3 $line = $line . $_;
4 if ($line =~ /^\@/) {
5 <IN>;
6 #next;
7 my $line = $line;
8 }
9 }
10 print "$line";
讨论每一行:
$line
。如果需要,可以写成$line .= $_;
@
开头的行之后的行。请注意,由于正则表达式上没有多行修饰符,因此它始终只匹配变量$line
中的第一个线段。由于过早连接,它将在每一行上匹配(因为第一行数据以@
开头),执行第5-8行中的代码。$_
。它没有测试EOF,但那是无害的。my $line = $line;
是一个隐藏外部$line
的新变量的自我赋值...主要是怪异,在较小程度上它是一个没有 - 运。您没有使用use strict;
和use warnings;
,因为如果您这样做,您会收到警告。 Perl专家使用use strict;
和use warnings;
来确保他们没有犯过愚蠢的错误;新手应该出于同样的原因使用它们。@
之后打印行,或者只对打印行号为2N + 2的整数N感兴趣,那么就没有必要在打印每一行之前在内存中构建整个字符串。打印出需要打印的每一行都会更简单。