如何对块中具有特定行的行块进行排序?

如何对块中具有特定行的行块进行排序?

我有一个包含这样数据的文件

BEGIN
hello2
5
world1
END
BEGIN
hello4
2
world5
END
BEGIN
hello6
4
END

我想根据块内的数字按以下方式对行进行排序。这些数字是孤立且唯一的。

BEGIN
hello4
2
world5
END
BEGIN
hello6
4
END
BEGIN
hello2
5
world1
END

我知道如何用 sed 和 awk 打印块。就是这样。

    # Prints the blocks including the BEGIN and END tags
    cat file | sed -n '/^BEGIN$/,/^END$/p'

    # Prints the blocks exluding the BEGIN and END tags
    awk '/^BEGIN$/ {show=1;next} /^END$/{show=0}  { print }' file

答案1

使用 GNU awk:

gawk '
    BEGIN { RS="\nEND\n"; ORS = RS; FS = "\n" }
    { record[$3] = $0 }
    END {
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (val in record) print record[val]
    }
' file

根据您的数据,我假设 BEGIN 和数字之间始终只有一行。

PROCINFO行定义了如何遍历“records”数组。看https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

答案2

每次BEGIN遇到一行时,使用单独的句柄通过 单独读取文件中的下一个数字行getline。使用两个前缀打印文件中的每一行,即先前检索到的数值当前记录的文件记录号(因此同一块内的所有行在BEGIN .. END前缀 1 中都具有相同的值,对应于块内嵌入的编号)。将其提供给外部sortcut实用程序,以通过丢弃前缀来处理基于前缀的排序。

awk '/BEGIN/{"awk \\$0+0==\\$0 "FILENAME | getline x}
{print x"~"FNR"~"$0 | "sort -k1,1n -k2,2n -t~ | cut -f3- -d~"}' file
BEGIN
hello4
2
world5
END
BEGIN
hello6
4
END
BEGIN
hello2
5
world1
END

答案3

第一行逐行聚合文本块,并尝试找到一个数字以用作随后的排序标准。当if 子句if($0+0==$0)找到一个数字时,它的值为 true。

当第二个块在输入中找到“END”时执行,因此它将块保存在关联数组中,并使用在块中找到的数字对其进行索引。

awk '{block=block"\n"$0; if($0+0==$0) num=$0;} 
/^END$/ {blks[num]=block; block=""} 
END {for(key in blks) print blks[key]}' file

最后一行只是在数组到达输入文件末尾时打印数组的每个条目。请注意,关联数组已经排序(这就是它内部的工作方式),因此我们只需要对其进行迭代并打印每个条目即可。

例如,查看以下awk脚本:

echo | awk '{a[2]="b"; a[1]="a"; a[3]="c"; for(key in a) print a[key];}'

它输出:

a
b
c

在我的回答中,我在每个块之前打印一个额外的内容\n,我想这不是问题。您的示例的输出是:

BEGIN
hello4
2
world5
END

BEGIN
hello6
4
END

BEGIN
hello2
5
world1
END

如果您不需要额外的行,请将awk脚本的第一块替换为:

{if(length(block)=="0")block=$0; else{block=block"\n"$0; if($0+0==$0) num=$0}}

这是单行版本:

awk '{if(length(block)=="0")block=$0; else{block=block"\n"$0; if($0+0==$0) num=$0}} /^END$/ {blks[num]=block; block=""} END {for(key in blks) print blks[key]}' file

相关内容