Text 如何合并奇数和偶数行?

Text 如何合并奇数和偶数行?,text,Text,我想把每一个偶数行和上面的行组合起来。比如: Line one,csv,csv,csv Line two,csv,csv Line three,csv,csv,csv,csv Line four,csv 第一行,csv,csv,csv 第二行,csv,csv 第三行,csv,csv,csv,csv 第四行,csv 结果应该如下所示: 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 第一行,csv,csv,csv 第二行,csv,csv 第三行,csv,csv,csv,csv 第四行,csv 结果应该如下所示:

Line one,csv,csv,csv,Line two,csv,csv Line three,csv,csv,csv,csv,Line four,csv 第一行,csv,csv,csv,第二行,csv,csv 第三行,csv,csv,csv,csv,第四行,csv 如何在Perl或sed/awk中实现这一点?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
#/usr/bin/perl
严格使用;使用警告;
我的$buffer;
while(我的$line=){
如果($.%2){
chomp$行;
$buffer=$line;
}
否则{
打印联接(“,”,$buffer,$line);
}
}
__资料__
第一行,csv,csv,csv
第二行,csv,csv
第三行,csv,csv,csv,csv
第四行,csv
输出:

C:\Temp> tt Line one,csv,csv,csv,Line two,csv,csv Line three,csv,csv,csv,csv,Line four,csv C:\Temp>tt 第一行,csv,csv,csv,第二行,csv,csv 第三行,csv,csv,csv,csv,第四行,csv在这里,有sed:

sed '$!N;s/\n/,/'
和awk:

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


通常,您会在缓冲区中累积数据,直到您有足够的时间知道输出什么,然后再输出数据

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

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

你不需要像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
还有一个:

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

你不需要引用这个?对于大多数shell。

一个稍微简单一些的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
#/usr/bin/perl
严格使用;
使用警告;
而(){
咀嚼;
打印“$”;
}
__资料__
第一行,csv,csv,csv
第二行,csv,csv
第三行,csv,csv,csv,csv
第四行,csv

这就是粘贴命令的作用。假设您的输出是使用
命令生成的,那么您可以执行以下操作:

$ command | paste -d, - -
或者如果输出存储在文件中

$ paste -d, - - <file.csv

甚至比
perl-pe'$|--| | s!$/!'还要短@mob,
$。%2&
$|--| |
一样短,但没有那么特别。我喜欢这个sed选项,而且速度非常快。有人能解释一下序列开头的“$!”是做什么的吗Ns/\n/,/'似乎得到了几乎相同的结果。@PieterMüller不需要
$N
N
命令试图读取文件末尾以外的内容时,它们将终止任何其他命令。但是,如果未设置
-n
选项,它仍将打印模式空间。在ubuntu上不起作用。只需连接第二行中的字符,这些字符从第一行结束的位置开始。如果您不关心尾随CV和行之间缺少的FS:)xargs-n2(“\n”是-d选项的默认值)的工作原理相同,似乎很容易记住。添加到我的收藏中的好技巧。我没听说过粘贴,我也不清楚这个问题应该用什么
过程来产生输出。更多详细信息?提供了用于粘贴的(Solaris)手册页。问题本身并没有说明输入是如何产生的。它是一个文件还是其他进程的输出?非常感谢链接,我的Cygwin手册页没有那么有用。在Cygwin上,
info-paste
将为您提供一个教程。
paste
使用默认的制表符分隔符将文件行合并在一起。如果将
-
指定为文件,则它会将其解释为STDIN。所以
粘贴-d,--
意味着:使用
作为分隔符而不是制表符,合并STDIN和STDIN中的行。如果您使用
粘贴-d,--
,它将每3行连接在一起,
-
将每4行连接在一起,依此类推。这太神奇了!
$ command | paste -d, - -
$ paste -d, - - <file.csv
paste -d, - - <<END
Line one,csv,csv,csv
Line two,csv,csv
Line three,csv,csv,csv,csv
Line four,csv
END