在Perl中,只有当第一个以冒号结尾时,如何才能将输入行与下一个输入行连接起来?

时间:2011-11-05 09:35:01

标签: perl

我的台词:

ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD

我想用冒号连接行结尾,下一行:

ABC: XYZ
XYZ ABC: XYZ
XYZ: ABC
XYZ
ABC: AAB
CCD

6 个答案:

答案 0 :(得分:1)

如果内容适合内存,请将其加载到单个变量中并执行以下操作:

$text =~ s/:\n/: /g

答案 1 :(得分:1)

我试图获得更美观的版本。

while (<DATA>) {
  chomp;
  print $_;
  print /:$/ ? " " : "\n";
}

更老,不愉快的尝试。 这个答案只保留当前行在内存中,它不需要啜饮输入也不需要在内存中构建整个输出。它还可以正确处理空数据,如果没有输入则不打印。

#!/usr/bin/env perl

use strict;
use warnings;

my $text;
while( my $line = <DATA> ) {
  if ($line =~ /:\s*\n/ && defined $text) {
      print $text;
      undef $text;
  }
  $line =~ s/:\s*\n/: /g;
  $text .= $line;
}
print $text if defined $text;

__DATA__
ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD

答案 2 :(得分:1)

如果您只想修复该文件,请使用以下命令行:

% perl -i.orig -pe 'chomp if /:$/' yourfile

如果您在输入循环中并且想要以冒号结尾的记录,请执行:

while (<>) {
    chomp;
    if (/:$/ && !eof) {
         $_ .= <>;
         redo unless eof;
    }
    # now you have your cuddled line(s), proceed as before
    ...
}

这假定文件的最后一行不是连续行。

答案 3 :(得分:1)

#!/usr/bin/env perl

use strict;
use warnings;

my $emit_eol;

while( my $line = <DATA> ) {
    $emit_eol = ($line =~ s/ : \s+ \z /: /x);
    print $line;
}

print "\n" if $emit_eol;

__DATA__
ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD:

答案 4 :(得分:0)

my $text;
{
  local $/= "";
  $text = <DATA>;
  $text =~ s/:\n/: /g;
}
print $text;

__DATA__
ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD

答案 5 :(得分:0)

到目前为止,这两个建议都建议将文件放入内存中,但是根据原始问题,这并不是绝对必要的。

#!/usr/bin/env perl

use strict;
use warnings;

my $text;
while( my $line = <DATA> ) {
    if ($line =~ s/ : \s+ \z /: /x) {
        $text .= $line;
    }
    else {
        print $text if is_nonempty_string($text);
        print $line;
        $text = '';
    }
}

print $text, "\n" if is_nonempty_string($text);

sub is_nonempty_string { defined($_[0]) and length($_[0]) }

__DATA__
ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD: