问题
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