2012-03-23 41 views
2

我需要讀取多行記錄並將它們修剪成完全40行。然後 填充它們爲45行。它們可能高達70多條線。這些記錄需要 最終爲45行。Perl:修剪多行記錄

記錄分隔符是以模式/ ^#matchee /開頭的行。

我假設你將$ /設置爲#matchee。

{ 
    $/ = "#matchee"; 

    while (<>) { 
     # I need to print first 40 
     # lines of each record then 
     # pad to 45 with delimiter as 
     # last line. 
    } 
} 

樣本記錄

REDUNDANCY DEPARTMENT 
Anonymous Ave 

Item 1 
Item 2 



<bunch of blank lines> 
#matchee 

回答

1

這裏是我的解決方案...

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

{ 
    $/ = "#matchee"; 

    while (my @line = split "\n", <>) { 

    # print first 40 lines of record 
     for my $counter (0..39) { 
      print($line[$counter] . "\n"); 
     } 

     # pad record with four extra blank lines 
     # (last record already ends with a newline) 
     print "\n" x 4; 
    } 
} 

+1使用$/ = "#matchee";

這是不完全正確......第一條記錄有45行,第二行有44行。

+1

'for my $ counter(0..39){...}' – vol7ron 2012-03-24 03:49:42

+0

好的建議。相應編輯的代碼。 – 2012-03-24 04:02:24

+0

如果使用更高版本的Perl,可以使用'say「...」;'而不是'print'... \ n「;但是,我不完全確定您是否設置了行終止變量。它也應該是'#!/ usr/bin/...'(沒有空格) – vol7ron 2012-03-24 04:13:08

1

指定「記錄分隔符是以模式/ ^#matchee /開頭的行」。這使記錄分離有點複雜,因爲$/a special string, but not a regex。您沒有指定您的輸出是否使用相同的記錄分隔符,但我假設如此。這是一種似乎可行的方法。

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

sub take_and_pad_lines { 
    my ($str, $take, $pad) = @_; 

    my @lines = (split(/\n/, $str))[0..$take-1]; 
    return join "\n", @lines, ('') x ($pad - $take); 
} 


{ 
    $/ = "#matchee"; 

    while (my $record = <>) { 
    # because RS is really begins-with we must clean up first line 
    # and double check last record 
    unless (1 == $.) { 
     $record =~ s/\A.*\n//m; 
     last if eof() && $record eq ''; 
    } 

    print take_and_pad_lines($record, 40, 45), "\n"; 
    print "$/\n" unless eof(); 
    } 
} 
+0

啊哈。這就解釋了爲什麼我在第一個和第二個記錄中包含不同數量的換行符......第一個記錄不是以分隔符開頭,因此比其他記錄短一行。 – 2012-03-24 16:00:01

+0

我會給這個鏡頭。謝謝! – Bubnoff 2012-03-25 03:24:29

+0

@Bubnoff爲你做了這個工作嗎? – dbenhur 2012-04-05 07:03:37