2011-03-20 112 views
0

使用perl寻找一个不区分大小写的搜索,所以如果一个“!”在行的开始处被检测到,新的排序开始(仅在该部分)。文本文件中的多重排序

[test file] 
! Sort Section 
! 
a 
g 
r 
e 
! New Sort Section 
1 
2 
d 
3 
h 

变,

[test file] 
! Sort Section 
! 
a 
e 
g 
r 
! New Sort Section 
1 
2 
3 
d 
h 
+0

在我的手机自动取款机,我有一个基本的排序会,但无法得到工作 – user349418 2011-03-20 12:51:24

回答

1

再一个,使用一个输出文件。更重要的是,不加载整个文件到内存:

use strict; 
use warnings; 
sub output { 
    my($lines, $fh) = @_; 
    return unless @$lines; 
    print $fh shift @$lines; # print first line 
    print $fh sort { lc $a cmp lc $b } @$lines; # print rest 
    return; 
} 
# ==== main ============================================================ 
my $filename = shift or die 'filename!'; 
my $outfn = "$filename.out"; 
die "output file $outfn already exists, aborting\n" if -e $outfn; 
# prereqs okay, set up input, output and sort buffer 
open my $fh, '<', $filename or die "open $filename: $!"; 
open my $fhout, '>', $outfn or die "open $outfn: $!"; 
my $current = []; 
# process data 
while (<$fh>) { 
    if (m/^!/) { 
     output $current, $fhout; 
     $current = [ $_ ]; 
    } 
    else { 
     push @$current, $_; 
    } 
} 
output $current, $fhout; 
close $fhout; 
close $fh; 
+0

我注意到unix格式化的文本文件在输出中变成了dos格式,是否有修复(保持原始文本格式)? ..脚本运行在win32环境下,谢谢:) – user349418 2011-03-21 00:22:52

+0

解决的办法是在文件句柄上调用'binmode'。 – Lumi 2011-03-21 00:45:21

2

下面是做这件事:

use strict; 
use warnings; 
my $filename = shift or die 'filename!'; 
my @sections; 
my $current; 
# input 
open my $fh, '<', $filename or die "open $filename: $!"; 
while (<$fh>) { 
    if (m/^!/) { 
     $current = [ $_ ]; 
     push @sections, $current; 
    } 
    else { 
     push @$current, $_; 
    } 
} 
close $fh; 
# output 
for (@sections) { 
    print shift @$_; # print first line 
    print sort @$_; # print rest 
} 
+0

章节位跳过不区分大小写方面。你可以像这样提供你的排序例程:'print sort {lc $ a cmp lc $ b} @ $ _; #print rest' – Lumi 2011-03-20 11:32:21

+0

这是否将输出保存到相同的文件名(需要),它也是win32兼容? – user349418 2011-03-20 12:53:41

+0

它将数据打印到STDOUT,您可以使用重定向将其写入所需位置。您还可以通过添加另一个调用来打开/关闭输出文件句柄来将内容写入文件,可能会转到'$ inputfilename.out'。不过,我强烈建议不要打破源文件。如果你想在那里放置一些重命名逻辑,Perl也会内置'rename'。 – Lumi 2011-03-20 13:31:12