根据 linux 中的条件合并后续行
Merge of subsequent lines based on conditions in linux
我的文件中有以下我的软件安装和升级时间的原始日志输出。我需要在 Excel 报告中记录软件升级的进度,并且需要采用预期输出格式的数据。起点是软件的安装,之后只是升级记录在日志中。
- 原始日志输出:
BIOS1,01/16/21 16:27:34,INSTALL,version-19.001-355
BIOS1,01/17/21 11:04:48,UPGRADE,version-19.001-361
BIOS1,02/14/21 07:22:37,UPGRADE,version-19.001-366
BIOS1,02/15/21 14:23:09,UPGRADE,version-19.001-372
所以基本上我需要从
发生的软件升级进程的信息
version-19.001-355 -> version-19.001-361 -> version-19.001-366 -> version-19.001-372
根据条件合并行后我的报告所需的预期输出如下所示,采用 csv 格式。有 From_Version 升级到 To_Version 的信息,升级日期为
Name, From_Version, Upgraded_Date_Time, State, To_Version
BIOS1, version-19.001-355, 01/17/21 11:04:48, UPGRADE, version-19.001-361
BIOS1, version-19.001-361, 02/14/21 07:22:37, UPGRADE, version-19.001-366
BIOS1, version-19.001-366, 02/15/21 14:23:09, UPGRADE, version-19.001-372
我尝试使用 :
合并行
awk 'NR%2 {printf("%s", [=13=]); next} {print [=13=]} ' data.txt
但数据刚刚合并,无法以所需方式获取。
跨行保持“版本”;来自当前处理行的是 to
而来自上一行的是 from
use warnings;
use strict;
use feature 'say';
die "Usage: [=10=] file\n" if not @ARGV;
say join ',', qw(Name From_Version Upgraded_Date_Time State To_Version);
my $install_line = <>; # shave off the first line
chomp $install_line;
my $from_version = (split /,/, $install_line)[-1];
while (<>) {
chomp;
my ($name, $ts, $state, $version) = split /,/;
say join ',', $name, $from_version, $ts, $state, $version;
$from_version = $version;
}
我在逗号周围没有留空格,因此它是一个合适的 CSV 文件(Excel 会喜欢)。
"null filehandle" <>
从命令行中给定的文件中读取行。所以你用这个作为
program_name filename
(使脚本 program_name
可执行,或执行 perl program_name filename
)
你可以使用这个awk
:
awk -F, -v OFS=', ' '
NR == 1 {
print "Name, From_Version, Upgraded_Date_Time, State, To_Version"}
NR > 1 {
= p OFS
print
}
{
p = $NF
}' file
Name, From_Version, Upgraded_Date_Time, State, To_Version
BIOS1, version-19.001-355, 01/17/21 11:04:48, UPGRADE, version-19.001-361
BIOS1, version-19.001-361, 02/14/21 07:22:37, UPGRADE, version-19.001-366
BIOS1, version-19.001-366, 02/15/21 14:23:09, UPGRADE, version-19.001-372
我的文件中有以下我的软件安装和升级时间的原始日志输出。我需要在 Excel 报告中记录软件升级的进度,并且需要采用预期输出格式的数据。起点是软件的安装,之后只是升级记录在日志中。
- 原始日志输出:
BIOS1,01/16/21 16:27:34,INSTALL,version-19.001-355
BIOS1,01/17/21 11:04:48,UPGRADE,version-19.001-361
BIOS1,02/14/21 07:22:37,UPGRADE,version-19.001-366
BIOS1,02/15/21 14:23:09,UPGRADE,version-19.001-372
所以基本上我需要从
发生的软件升级进程的信息
version-19.001-355 -> version-19.001-361 -> version-19.001-366 -> version-19.001-372
根据条件合并行后我的报告所需的预期输出如下所示,采用 csv 格式。有 From_Version 升级到 To_Version 的信息,升级日期为
Name, From_Version, Upgraded_Date_Time, State, To_Version
BIOS1, version-19.001-355, 01/17/21 11:04:48, UPGRADE, version-19.001-361
BIOS1, version-19.001-361, 02/14/21 07:22:37, UPGRADE, version-19.001-366
BIOS1, version-19.001-366, 02/15/21 14:23:09, UPGRADE, version-19.001-372
我尝试使用 :
合并行awk 'NR%2 {printf("%s", [=13=]); next} {print [=13=]} ' data.txt
但数据刚刚合并,无法以所需方式获取。
跨行保持“版本”;来自当前处理行的是 to
而来自上一行的是 from
use warnings;
use strict;
use feature 'say';
die "Usage: [=10=] file\n" if not @ARGV;
say join ',', qw(Name From_Version Upgraded_Date_Time State To_Version);
my $install_line = <>; # shave off the first line
chomp $install_line;
my $from_version = (split /,/, $install_line)[-1];
while (<>) {
chomp;
my ($name, $ts, $state, $version) = split /,/;
say join ',', $name, $from_version, $ts, $state, $version;
$from_version = $version;
}
我在逗号周围没有留空格,因此它是一个合适的 CSV 文件(Excel 会喜欢)。
"null filehandle" <>
从命令行中给定的文件中读取行。所以你用这个作为
program_name filename
(使脚本 program_name
可执行,或执行 perl program_name filename
)
你可以使用这个awk
:
awk -F, -v OFS=', ' '
NR == 1 {
print "Name, From_Version, Upgraded_Date_Time, State, To_Version"}
NR > 1 {
= p OFS
print
}
{
p = $NF
}' file
Name, From_Version, Upgraded_Date_Time, State, To_Version
BIOS1, version-19.001-355, 01/17/21 11:04:48, UPGRADE, version-19.001-361
BIOS1, version-19.001-361, 02/14/21 07:22:37, UPGRADE, version-19.001-366
BIOS1, version-19.001-366, 02/15/21 14:23:09, UPGRADE, version-19.001-372