Как объединить нечетные и четные строки? - PullRequest
5 голосов
/ 21 октября 2011

Я хочу объединить каждую четную строку со строкой над ней.Примерно так:

Line one,csv,csv,csv
Line two,csv,csv
Line three,csv,csv,csv,csv
Line four,csv

Результат должен выглядеть следующим образом:

Line one,csv,csv,csv,Line two,csv,csv
Line three,csv,csv,csv,csv,Line four,csv

Есть идеи, как этого добиться в Perl или sed / awk?

Ответы [ 7 ]

11 голосов
/ 21 октября 2011

вот оно, с sed:

sed '$!N;s/\n/,/'

и с awk:

awk '{if (e) {print p","$0;} else {p=$0;} e=!e;}'

или

awk 'NR%2==0 {print p","$0;} NR%2 {p=$0;}'
5 голосов
/ 21 октября 2011

Для этого и используется команда paste:

process_to_produce_output | paste -d, - -

Пример:

$ paste -d, - - <<END
> Line one,csv,csv,csv
> Line two,csv,csv
> Line three,csv,csv,csv,csv
> Line four,csv
> END
Line one,csv,csv,csv,Line two,csv,csv
Line three,csv,csv,csv,csv,Line four,csv
2 голосов
/ 21 октября 2011

Как правило, вы будете накапливать данные в буфере, пока у вас не будет достаточно информации о том, что выводить, а затем вывести данные.

my @buf;
while (<>) {
    chomp;
    if (!@buf) {
       push @buf, $_;
       next;
    }

    my $line1 = shift(@buf);
    my $line2 = $_;
    print("$line1,$line2\n");
}

Но в этом случае существует гораздо более простое решение, посколькуВаша проблема может быть сформулирована следующим образом: Замените каждую вторую новую строку запятой, начиная с первой.

perl -pe's/\n/,/ if $. % 2' file
2 голосов
/ 21 октября 2011

Встроенная переменная Perl $. сообщит вам номер строки. $. % 2 будет 1, если $. нечетно, и 0 в противном случае. Вот отдельный пример:

#!/usr/bin/perl

use strict; use warnings;

my $buffer;

while (my $line = <DATA>) {
    if ($. % 2) {
        chomp $line;
        $buffer = $line;
    }
    else {
        print join(",", $buffer, $line);
    }
}

__DATA__
Line one,csv,csv,csv
Line two,csv,csv
Line three,csv,csv,csv,csv
Line four,csv

Выход:

C:\Temp> tt
Line one,csv,csv,csv,Line two,csv,csv
Line three,csv,csv,csv,csv,Line four,csv
1 голос
/ 21 октября 2011

Немного более простое решение Perl.

#!/usr/bin/perl

use strict;
use warnings;

while (<DATA>) {
  chomp;
  print "$_," . <DATA>;
}

__DATA__
Line one,csv,csv,csv
Line two,csv,csv
Line three,csv,csv,csv,csv
Line four,csv
1 голос
/ 21 октября 2011

И еще один:

awk -F, ORS=NR%2\?FS:RS infile

Вам не нужно цитировать? с большинством снарядов .

1 голос
/ 21 октября 2011

вам не нужно такое ядерное оружие, как perl / sed / awk, чтобы решить эту проблему. xargs достаточно.

xargs -d '\n' -n2

тест

kent$  echo "Line one,csv,csv,csv
Line two,csv,csv
Line three,csv,csv,csv,csv
Line four,csv"|xargs -d '\n' -n2
Line one,csv,csv,csv Line two,csv,csv
Line three,csv,csv,csv,csv Line four,csv
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...