如何合并文件中的每n行

时间:2017-05-23 16:14:22

标签: bash unix awk sed

我正在尝试将类似的线组加入一行。我的文件是基本的日志类型文件,但每个条目跨越三行,后跟换行符。例如:

Timestamp
key1 | val1 | key2 | val2
key3 | val3 | key4 | val4

Timestamp
key1 | val1 | key2 | val2
key3 | val3 | key4 | val4

我想要的是每个3行的块在一个逗号分隔的行上:

Timestamp,key1,val1,key2,val2,key3,val3,key4,val4

如果我只需处理键/值行,我可以使用sed& awk执行此操作,但我的问题是获取每行的时间戳。

我看过的事情正在使用xargspaste,但似乎都没有做我需要他们做的事情。

6 个答案:

答案 0 :(得分:4)

$ awk -v RS= -F'\n| \\| ' -v OFS=',' '{$1=$1}1' file
Timestamp,key1,val1,key2,val2,key3,val3,key4,val4
Timestamp,key1,val1,key2,val2,key3,val3,key4,val4

答案 1 :(得分:3)

sedpaste

的替代解决方案
$ sed 's/ *| */,/g;/^$/d' file | paste -d, - - -

Timestamp,key1,val1,key2,val2,key3,val3,key4,val4
Timestamp,key1,val1,key2,val2,key3,val3,key4,val4

读起来像: 用逗号替换分隔符,删除空行,一次用逗号分隔符粘贴3行。

答案 2 :(得分:2)

这可能适合你(GNU sed):

sed -n 'N;N;s/ *[|\n] */,/pg;n' file

在模式空间中读取3行,用逗号替换管道或换行符(可能用空格包围),打印成功替换并丢弃空行。

答案 3 :(得分:1)

这个awk使用内置RS变量来简化记录之间的移动。我们检测是否在时间戳行上并设置ts变量。然后,因为我们设置RS $1$NF将是我们的键值字段,所以迭代它们并将它们附加到输出字符串。我们将最后一个保存在循环外部,这样我们就可以避免悬空,。然后我们只打印行并继续前进。

BEGIN{
    RS="\n\n";  # Everything between blank lines will be treated as one record
    FS="|";     # Our fields are separated with pipes.
}
{ 
    if( NF == 1 ){   # The number of fields on this line is 1... only our timestamp lines look like this.
        ts=$1;      
        next;       # Go to next record.
    };  



    # Build up an output buffer while avoiding dangling ","   
    out="";          

    for( i=1; i < NF; i++ ){
        out=out$i","
    } 

    out=out$NF; 

    print ts","out 
}

答案 4 :(得分:0)

尝试:

awk '/^Timestamp/ && VAL{print VAL;VAL=$0;next} {gsub(/ +\| +/,",");VAL=VAL?VAL OFS $0:$0} END{print VAL}' OFS=","   Input_file

查找字符串Timestamp和VAL,如果它们都有值,则打印变量VAL的值,然后将VAL分配给当前行,并提及下一个跳过所有进一步的语句。然后,如果这个条件不满足,那么全局代替空间|使用逗号的空格,然后创建一个名为VAL的变量,其值将每次与它自己的值连接。然后在END部分还打印VAL的值,因为VAL可能存在于那里。

答案 5 :(得分:0)

一些愚蠢的 sed-only 技巧:

sed -n -e '/Timestamp/{h;n};s/ | /,/g;H;/^$/{g;s/\n/,/g;s/,$//;p}' file

  • 仅在使用sed -n命令时使用p进行打印
  • /Timestamp/{h;n}; 保留空间替换为时间戳行,然后转到下一行输入
  • s/ | /,/g;H;用逗号替换栏,追加到暂停空间
  • /^$/{g;s/\n/,/g;s/,$//;p}在空白行保留空间的内容保存到模式空间中,s/\n/,/g用逗号替换换行符,最后s/,$//;p删除尾随逗号并打印模式空间

输入file

Timestampa
key1 | val1 | key2 | val2
key3 | val3 | key4 | val4

Timestampb
key1 | val1 | key2 | val2
key3 | val3 | key4 | val4

输出:

Timestampa,key1,val1,key2,val2,key3,val3,key4,val4
Timestampb,key1,val1,key2,val2,key3,val3,key4,val4

s/\n/,/g可能与系统/ sed版本有关。