How can I combine odd and even numbered lines?

流过昼夜 提交于 2020-12-29 10:04:28

问题


I want to combine every even-numbered line with the line above it. Something like:

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

The result should look like this:

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

Any ideas how to achieve that in either Perl or sed/awk?


回答1:


Perl's builtin variable $. will tell you the line number. $. % 2 will be 1 if $. is odd, and 0 otherwise. Here is a self-contained example;

#!/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

Output:

C:\Temp> tt
Line one,csv,csv,csv,Line two,csv,csv
Line three,csv,csv,csv,csv,Line four,csv



回答2:


here it is, with sed:

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

and with awk:

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

or

awk 'NR%2==0 {print p","$0;} NR%2 {p=$0;}'



回答3:


This is what the paste command is for. Assume your output is generated with command, then you can do:

$ command | paste -d, - -

or if the output is stored in a file

$ paste -d, - - <file.csv

Example:

$ 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



回答4:


And another one:

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

You don't need to quote the ? with most shells.




回答5:


Generally, you'd accumulate data in a buffer until you have enough to know what to output, then you output the data.

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

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

But in this case, there exists a much simpler solution since your problem can be restated to be: Replace every second newline with a comma, starting with the first.

perl -pe's/\n/,/ if $. % 2' file



回答6:


you don't need those nuclear weapons like perl/sed/awk to solve this problem. xargs is enough.

xargs -d '\n' -n2

test

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



回答7:


A slightly simpler Perl solution.

#!/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


来源:https://stackoverflow.com/questions/7841607/how-can-i-combine-odd-and-even-numbered-lines

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!