将多行连接成一行,直到找到模式而不会丢失模式的第一部分

将多行连接成一行,直到找到模式而不会丢失模式的第一部分

我有以下模式:

i-095erwr244r22cfeaa
TF-CLIENT
TF-StKML2
i-0c23232ac153534c5d
TF-CLIENT
TF-COMMON
TF-STEERR
i-043434e0934347eb5
TF-CLIENT
TF-ADFS
TF-COMMON
TF-STCLUSTER_1
TF-SwewCLUSTER3

我想要以下输出

i-095erwr244r22cfeaa,TF-COMMON;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3

我尝试这样:

awk 'BEGIN{RS="i-"}NF>1{print substr(gensub(/\n/,";","g"),0,length($0)-0)}' sg1.txt

基于类似的帖子在这里我得到以下结果

095erwr244r22cfeaa;TF-COMMON;TF-StKML2;
0c23232ac153534c5d;TF-CLIENT;TF-COMMON;TF-STEERR;
043434e0934347eb5;TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3

所以它正在剪切模式“i-0”的开头,并向所有输出添加分号,我需要第一个是逗号。我想过使用sed替换结果中的第一个分号,但如何才能在开始时获得完整的输出?

答案1

我的 GNUsed提案tr

tr '\n' ';' < file | sed -E 's/(i-0[^;]*);/\n\1,/g'

输出:

i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3;

答案2

$ awk '/^i-/{if (NR>1) print rec; rec=$0 ","; next} {rec=rec $0 ";"} END{print rec}' file
i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3;

或者,取决于您是否希望在每行末尾有分号:

$ awk '/^i-/{if (NR>1) print rec; rec=$0; sep=","; next} {rec=rec sep $0; sep=";"} END{print rec}' file
i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3

答案3

你有:

BEGIN { RS="i-" }
NF>1 {
    print substr( gensub(/\n/,";","g"), 0, length($0)-0)
}

在这里,您将多行转换为一条记录,用“i-”分隔,这样它就会立即丢失,并将 NL (“\n”) 转换为 ';'。 substr 似乎对你没有多大作用。

根子本身重复应用可以满足您的需要,如下所示......

BEGIN { RS="i-" }
NF>1 {
    print gensub("^(.*);$", "i-\\1", "g", gensub(/\n/,";","g"))
}

这依赖于内部 gensub 执行您之前所做的操作,连接多个字段,将 NL 转换为“;”。外部简单地将其作为输入,将“i-”添加回开头并修剪“;”在最后。

在 1 行中:

awk 'BEGIN{RS="i-"}NF>1{print gensub("^(.*);$", "i-\\1", "g", gensub(/\n/,";","g"))}' sg1.txt

这是一种相当复杂的做事方式。更自然的做法是简单地表达您正在做的事情,如下所示:

/^i-/ {
    if (line) print line;
    line=$0;
    next
}
{
    line = line";"$0
}
END {
    if (line) print line
}

当您看到带有 ^i- 的行时,打印旧状态并开始新行。其余的,追加。冲洗,重复。记得在最后打印。

第一次,测试并打印。在结束时,测试并打印,以防你得到一个空文件。

答案4

使用终端打印每条记录(行);,除非该行以 a 开头,否则i-将打印如下:

$ awk -vORS=\; '/^i-/{printf "%s%s,",a,$0 ; a="\n";next}1;END{printf "\n"}' file

i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3;

相关内容