Bash 如何合并文件中的每n行
我试着把类似的几组线连接到一条线上。我的文件是一个基本的日志类型文件,但每个条目跨越三行,后跟一个换行符。例如:Bash 如何合并文件中的每n行,bash,unix,awk,sed,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,key
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实现这一点,但我的问题是获取每行的时间戳
我看到的东西正在使用,但它们似乎都没有达到我所需要的效果。试试:
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的变量,该变量的值每次都将与其自身的值连接。然后在最后一节也打印VAL的值,因为VAL可能在那里 试试看:
awk '/^Timestamp/ && VAL{print VAL;VAL=$0;next} {gsub(/ +\| +/,",");VAL=VAL?VAL OFS $0:$0} END{print VAL}' OFS="," Input_file
$ 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
查找字符串Timestamp和VAL(如果两者都有值),然后打印变量VAL的值,然后将VAL分配到当前行,并提及下一行以跳过所有其他语句。如果不满足此条件,则用逗号全局替换空格|空格,然后生成一个名为VAL的变量,该变量的值每次都将与其自身的值连接。然后在最后一节也打印VAL的值,因为VAL可能在那里 此awk使用内置RS变量简化记录之间的移动。我们检测是否在时间戳行上,如果在时间戳行上,则设置
ts
变量。然后,由于我们将RS$1
设置为通过$NF
将是我们的键、值字段,因此迭代它们并将它们附加到输出字符串中。我们将最后一个保存在循环外部,这样就可以避免出现悬空的,
。然后我们只需打印该行并继续
$ 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
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
}
开始{
RS=“\n\n”#空行之间的所有内容都将被视为一条记录
FS=“|”;#我们的田地用管道隔开。
}
{
如果(NF==1){#这一行上的字段数是1…只有我们的时间戳行是这样的。
ts=$1;
下一张;#转到下一张唱片。
};
#建立输出缓冲区,同时避免挂起“,”
out=“”;
对于(i=1;i
此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
}
开始{
RS=“\n\n”#空行之间的所有内容都将被视为一条记录
FS=“|”;#我们的田地用管道隔开。
}
{
如果(NF==1){#这一行上的字段数是1…只有我们的时间戳行是这样的。
ts=$1;
下一张;#转到下一张唱片。
};
#建立输出缓冲区,同时避免挂起“,”
out=“”;
对于(i=1;i
使用sed
和粘贴的替代解决方案
$ 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行,中间使用逗号分隔符。使用
sed和粘贴的替代解决方案
$ 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行,中间用逗号分隔符。一些愚蠢的仅sed技巧:
sed-n-e'/Timestamp/{h;n};s/|/,/g;H/^$/{g;s/\n/,/g;s/,$/;p}文件
- 使用
sed-n
仅在使用p
命令时打印
/Timestamp/{h;n}代码>将保留空间替换为时间戳行,并移到下一行输入
s/|/,/g;H代码>将条形替换为逗号并附加到保留空间
- 空行上的
/^$/{g;s/\n/,/g;s/,$/;p}
将保留空间的内容放入模式空间,s/\n/,/g
用逗号替换换行符,最后s/,$/;p
删除尾随逗号并打印图案空间
输入文件
:
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版本。一些愚蠢的仅sed技巧:
sed-n-e'/Timestamp/{h;n};s/|/,/g;H/^$/{g;s/\n/,/g;s/,$/;p}文件
- 使用
sed-n
仅在使用p
命令时打印
/Timestamp/{h;n}代码>将保留空间替换为时间戳行,并移到下一行输入
s/|/,/g;H代码>将条形替换为逗号并附加到保留空间
- 空行上的
/^$/{g;s/\n/,/g;s/,$/;p}
将保留空间的内容放入模式空间,s/\n/,/g
用逗号替换换行符,最后s/,$/;p
删除尾随逗号并打印图案空间
输入文件
:
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版本有关。这可能适用于您(GNU-sed):
在模式空间中读入3行,用逗号替换管道或换行符(可能被空格包围),打印成功的替换并丢弃空行。这可能适合您(GNU-sed):
在模式空间中读3行,用逗号替换管道或换行符(可能被空格包围),打印成功