如何使用perl在2行块中复制和追加字符串

时间:2015-10-06 06:11:51

标签: perl

while ($line = <IN>){
    ...
print OUT "$line";
print OUT1 "$line";
}

据我所知,我的while循环一次只读取一行输入文件。如何调整它以使其一次读取2行?

假设一个2行的块看起来像这样

%line1
THISISLINE2

我希望我的while循环复制第一行并将其粘贴到第二行之后(但将%替换为@)。我还想添加一行11个字符A作为第4行。基本上我希望输出为

 %line1
 THISISLINE2
 @line1
 AAAAAAAAAAA

如何编写while循环来执行此操作?

5 个答案:

答案 0 :(得分:3)

I am going to make a guess that you've got multi-line records like this:

%line1
something something line1
%lineB 
something to do with lineb

I would suggest in this scenario - rather than reading two lines at a time, you instead set your record separator via $/.

E.g.:

#!/usr/bin/env perl;
use strict;
use warnings;

local $/ = "%";

while (<DATA>) {
    chomp;
    my @lines = split "\n";
    next unless @lines;
    print '%', join( "\n", @lines ), "\n";
    print $lines[0] =~ s/^/\@/r, "\n";
    print "Something else to do with record $.\n";
    print "---END---\n";
}

__DATA__
%line1
something something line1
%lineB 
something to do with lineb

This means that each iteration of the while loop - it reads until the next % symbol. As a result, the first iteration is empty, but subsequent records will work fine.

This prints:

%line1
something something line1
@line1
Something else to do with record 2
---END---
%lineB 
something to do with lineb
@lineB 
Something else to do with record 3
---END---

答案 1 :(得分:1)

以下是一个可以同时获得两行的循环选项:

my $l1;
my $l2;
while (defined($l1=<DATA>) and defined($l2=<DATA>))
{
    print "line 1: $l1\n";
    print "line 2: $l2\n";
}

__DATA__
line1
line2
line3
line4
line5

这不需要先将整个文件读入数组。

它也会忽略文件末尾的一行(但您可以通过切换到or来更改它。)

答案 2 :(得分:0)

#!/usr/bin/perl
use strict;
use warnings;

open (my $fh, "<", "test.txt") or die $!;
open (my $op, ">", "output.txt") or die $!;

my @slurp = <$fh>;

while(my @lines = splice(@slurp, 0, 2)){
    my ($line1, $line2) = @lines;   
    print $op $line1;
    print $op $line2;
    if($line1 =~ s/%/@/){
        print $op $line1;           
        if($line2 =~ tr/.*/A/c){
            print $op $line2."\n";
        }   
    }
}

答案 3 :(得分:0)

你可以使用for循环代替while吗?请记住for需要将整个文件读入内存。但除非你有非常高的性能标准和非常大的数据文件,否则它不应该成为问题。

open IN,"<",$file;
my @lines = <IN>;
for (my $i = 0;$i le $#lines; $i = $i+2) {
    my $first_line = $lines[$i];
    my $second_line = $lines[$i+1];
}

答案 4 :(得分:0)

您的问题看起来像一个简单的finite-state machine的可能用例:

use strict;
use warnings;

my $state = 1;
my $first_line;

while (<>) {
    if ($state == 1) {
         $first_line = $_;
         $state = 2;
    } elsif ($state == 2) {
         # do whatever you want with $_ and $first_line
         $state = 1;
    } else {
         die "Unknown state '$state', not sure how we got here";
    };
};