2009-04-22 7 views

答えて

9

奇数要求が、これはそれを行う必要があります。

#!/usr/bin/perl 

use strict; 
use warnings; 

my $s = join '', map { "$_\n" } 1 .. 9; 

my ($first) = $s =~ /^((?:.*\n){0,5})/; 
my ($last) = $s =~ /((?:.*\n){0,5})$/; 


print "first:\n${first}last:\n$last"; 

より一般的な解決策は、このようなものになるだろう:ブライアンが言うように

#!/usr/bn/perl 

use strict; 
use warnings; 

#fake a file for the example  
my $s = join '', map { "$_\n" } 1 .. 9;  
open my $fh, "<", \$s 
    or die "could not open in memory file: $!"; 

my @first; 
while (my $line = <$fh>) { 
    push @first, $line; 
    last if $. == 5; 
} 

#rewind the file just in case the file has fewer than 10 lines 
seek $fh, 0, 0; 

my @last; 
while (my $line = <$fh>) { 
    push @last, $line; 
    #remove the earliest line if we have to many 
    shift @last if @last == 6; 
} 

print "first:\n", @first, "last:\n", @last; 
+0

これは最後の5行にどのように適用されますか? – Tanami

+0

my($ last_five_lines)= $ s =〜/(((??.*\n){5})¥z/; –

+0

あなたは{0,5}修飾子が必要です。そうでなければ、4行の文字列を拒否します(そうでない限り)。 –

6

なぜそれにheadを使用しないのですか?

+0

Perlプログラムであり、一時ファイルを作成したくない場合は、これを行うことはできません。 –

+0

@brian d foy Hmm、真実ではありません。あなたは向けるために双方向性のパイプを開くことができます。それは愚かなことですが、あなたはそれを行うことができます。 –

+1

双方向パイプを開くことはできますか? Perlは多くの場所で動作します。 :) –

2
my ($first_five) = $s =~ /\A((?:.*\n){5})/; 
my ($last_five) = $s =~ /((?:.*\n){5})\z/; 
2

、あなたがheadtailを使用することができますいずれかの問題(最初の5行または最後の5行)に対してはかなり簡単です。

しかし、今私はあなたの質問を正しく理解しているのだろうかと思っています。あなたが「あらゆる種類のスカラーについて」と言うと、(何らかの理由で)そのファイルが既にスカラーに入っているということを意味しますか?

もしそうでなければ、最良の解決策は正規表現ではないと私は思います。 $.を使用し、ファイルを通常または後方に読み取ります。後ろを読むには、File::ReadBackwardsまたはFile::Bidirectionalを試してみてください。

+0

ファイルが非常に長い場合、File :: ReadBackwardsは素晴らしいです。 –

1

人々いくつかの重要なフラグが不足している:マルチラインフラグなし

/(?m)((?:^.*\n?){1,5})/ 

は、最初の行だけを見て起こっています。また、\nをオプションにすることで、最初の5つの行をの5番目の末尾に改行に関係なく使用できます。

3

正規表現は必要ありません。

my $scalar = ...; 

open my($fh), "<", \ $scalar or die "Could not open filehandle: $!"; 
foreach (1 .. 5) 
    { 
    push @lines, scalar <$fh>; 
    } 
close $fh; 

$scalar = join '', @lines; 
+0

Brian - これは、open()コールで$ fhを2回参照するタイプミスですか? – Alnitak

1

はなぜだけではなく、制限と分割を使用し、それは、この目的のために設計されています:

ただ、スカラーへの参照にファイルハンドルを開くには、あなたがファイルハンドルの他の並べ替えのためにするのと同じことを行います
my @lines = (split /\n/, $scalar, 6)[0..4]; 

あなたは5行で単一のスカラーとしてそれをバックしたい場合は、最大戻ってそれに参加する:あなたの大切な文字列が内側にある場合

my $scalar = join('\n', @lines) . "\n"; 
0
use strict; 


my $line; #Store line currently being read 
my $count=$ARGV[1]; # How many lines to read as passed from command line 
my @last; #Array to store last count lines 
my $index; #Index of the line being stored 


#Open the file to read as supplied from command line 
open (FILE,$ARGV[0]); 
while ($line=<FILE>) 
{ 
    $index=$.%$count; # would help me in filter just $count records of the file 
    $last[$index]=$line; #store this value 
} 
close (FILE); 

#Output the stored lines 
for (my $i=$index+1;$i<$count;$i++) 
{ 
    print ("$last[$i]"); 
} 
for (my $i=$0;$i<=$index;$i++) 
{ 
    print ("$last[$i]"); 
} 
関連する問題