コロン(perl)の後に行を結合する

私はこの行を持っています:

alpha: beta
beta: alpha, beta
omega: beta, gamma, alpha
gamma: 
alpha
beta
gamma
epsilon: alpha

私は行に参加したいと思っています。

alpha: beta
beta: alpha, beta
omega: beta, gamma, alpha
gamma: alpha, beta, gamma
epsilon: alpha
0
最初の行がコロンで終わっていない場合はどうなりますか?最初の2行がコロンで終わっていない場合は?
追加された 著者 Bill Ruppert,

3 答え

入力がファイルへの引数としてスクリプトに提供され、少し短くなっている場合にもこれが有効です:

$/=$.;$_=<>;s/\s?\n/, /g;s/, (\w+:),?/\n$1/g;s/, $/\n/;print

これはあまり読みにくくはありませんが、 strict warnings で動作します。

出力:

alpha: beta
beta: alpha, beta
omega: beta, gamma, alpha
gamma: alpha, beta, gamma
epsilon: alpha

それはおそらくさらに短くすることができます。 -ape または#!perl -ap は良いスタートになります。

1
追加された

クイックで汚れたバージョンです:

#!/usr/bin/perl

use strict;
use warnings;

my $prevLine = "";
my @others;

for() {
    chomp;
    if (/:\s*$/) { # lines ends with : and potential space after
        $prevLine = $_;
    } elsif (!/:/) { # line doesn't contain ':'
        push(@others, $_);
    } elsif ($prevLine eq "") { # this is a "x: y, z" line, nothing in buffer
        print $_ . "\n";
    } else { # this is a "x: y, z" line, with a previous line in buffer
        print $prevLine . join(", ", @others) . "\n" . $_ . "\n";
    }
}

__DATA__
alpha: beta
beta: alpha, beta
omega: beta, gamma, alpha
gamma: 
alpha
beta
gamma
epsilon: alpha

出力:

alpha: beta
beta: alpha, beta
omega: beta, gamma, alpha
gamma: alpha, beta, gamma
epsilon: alpha
1
追加された

これはRCコードと同じようにすべきですが、少し短くなります:

my @lines;
while() {
    chomp;
    if(m/^\w+:\s(\w+(,\s)?)*$/) {
            push @lines, $_;
    } else {
            $lines[$#lines] .= ", " unless($lines[$#lines] =~ m/^\w+:\s?$/);
            $lines[$#lines] .= $_;
    }
}
print join "\n", @lines;
1
追加された