使用awk打印已排序的输出以避免管道排序命令

使用awk打印已排序的输出以避免管道排序命令,awk,Awk,我正在尝试匹配包含(123)的行,然后操作字段2,将x和+替换为4列的空格。然后将第3列的顺序更改为第4列。 最后按第3列和第4列排序打印 我能够以这种方式在awk输出之后获得输出管道sort命令 $echo” 0:1920x1663+0+0 kpwr(746) 323:892x550+71+955 kpwr(746) 211:891x550+1003+410 kpwr(746) 210:892x451+71+410 kpwr(746) 415:891x451+1003+1054 kpwr(74

我正在尝试匹配包含
(123)
的行,然后操作字段2,将
x
+
替换为4列的空格。然后将第3列的顺序更改为第4列。 最后按第3列和第4列排序打印

我能够以这种方式在
awk
输出之后获得输出管道
sort
命令

$echo”
0:1920x1663+0+0 kpwr(746)
323:892x550+71+955 kpwr(746)
211:891x550+1003+410 kpwr(746)
210:892x451+71+410 kpwr(746)
415:891x451+1003+1054 kpwr(746)
1:894x532+70+330 kpwr(123)
324:894x532+1001+975 kpwr(123)
2:894x631+1001+330 kpwr(123)
212:894x631+70+876 kpwr(123)
61:892x1+71+375 kpwr(0)
252:892x1+71+921 kpwr(0)”
awk'/\(123\)/{b=gensub(/(.+)x(.+)\+(.+)\+(.+)/,“\\1\\2\\4\\3”,“g”,$2);打印b}'
排序-k3-k4-n
894 532 330 70
894 631 330 1001
894 631 876 70
894 532 975 1001

如何仅使用awk而不需要管道
排序
,就可以获得相同的输出?谢谢您的帮助。

您能处理GNU awk吗?:

$ gawk '
BEGIN {
    PROCINFO["sorted_in"]="@val_num_asc"              # for order strategy
}
/\(123\)$/ {                                          # pick records
    split($2,t,/[+x]/)                                # split 2nd field
    if((t[4] in a) && (t[3] in a[t[4]])) {            # if index collision
        n=split(a[t[4]][t[3]],u,ORS)                  # split stacked element
        u[n+1]=t[1] OFS t[2] OFS t[4] OFS t[3]        # add new data
        delete a[t[4]][t[3]]                          # del before rebuilding
        for(i in u)                                   # sort on whole record
            a[t[4]][t[3]]=a[t[4]][t[3]] ORS u[i]      # restack to element
    } else
        a[t[4]][t[3]]=t[1] OFS t[2] OFS t[4] OFS t[3] # no collision, just add
}
END {
    PROCINFO["sorted_in"]="@ind_num_asc"              # strategy on output

    for(i in a)           
        for(j in a[i])
            print a[i][j]
}' file
输出:

894 532 330 70
894 631 330 1001
894 631 876 70
894 532 975 1001
使用冲突数据,如:

1:   894x532+70+330    kpwr(123)  # this 
1:   123x456+70+330    kpwr(123)  # and this, notice order
324: 894x532+1001+975  kpwr(123)
2:   894x631+1001+330  kpwr(123)
212: 894x631+70+876    kpwr(123)
产出将是:

123 456 330 70                    # ordered by the whole record when collision
894 532 330 70
894 631 330 1001
894 631 876 70
894 532 975 1001

以下是如何从
awk
(gnu)本身获取它:

awk'/\(123\)/{
$2=gensub(/(.+)x(.+)\+(.+)\+(.+)/,“\\1\\2\\4\\3”,“g”,“$2)
拆分($2,a)#按空间拆分并存储到数组中
#按索引3和4存储数组
rec[a[3]][a[4]=(rec[a[3]][a[4]]=“”?“”:rec[a[3]][a[4]]ORS)$2
}
结束{
PROCINFO[“排序的”]=“@ind_num_asc”#按数字键升序排序
对于(记录中的i)#打印存储的数组记录
对于(记录中的j[i])
打印记录[i][j]
}"档案"
894532330 70
894 631 330 1001
894 631 876 70
894 532 975 1001

我几乎写完了,我的解决方案与@anubhava的解决方案一样,因此在他的解决方案中添加了一些调整:)这个解决方案将处理多行相同值的行

awk'
开始{
PROCINFO[“排序在”]=“@ind\u num\u asc”
}
/\(123\)/{
$2=gensub(/(.+)x(.+)\+(.+)\+(.+)/,“\\1\\2\\4\\3”,“g”,“$2)
拆分($2,a,“)
arr[a[3]][a[4]=(arr[a[3]][a[4]!=”?arr[a[3]][a[4]]ORS:”)$2
}
结束{
对于(我在arr中){
对于(j in arr[i]){print arr[i][j]}
}
}'输入文件

您最好使用管道进行排序
awk
没有任何很好的排序能力,因为
awk
中的数组是关联的
awk
是根据需要操作列数据的正确工具,但
sort
是随后对行重新排序的正确工具。@JamesBrown感谢您的解决方案和解释,这对理解代码有很大帮助。它可以显示正确的输出。您以前的代码添加了
1:123x456+70+330 kpwr(123)
后,我在输出中重复了几行。我看到您修改了代码,现在输出是正确的。非常感谢您让我们知道这个问题。是的,我忘记在重建之前重置
a[][]
中的元素。对不起,没问题。非常感谢你的帮助。我不确定哪种解决方案更好,因为我不是专家。我选择anubhava的因为它比较短。这是我的标准。非常感谢您的解决方案和处理具有相同值的多行的功能。非常好的point Ravinder用于处理同一键的多个值。只需一个小问题,
val==”
最好在
awk
中检查空字符串。只要检查
val
就返回false,如果它等于零。@anubhava,当然,先生,现在看起来不错了吗,先生,请确认一下,先生。是我的眼睛还是代码字体变为斜体了?实际上,首先我以为只有我的眼睛看到斜体:)但我想知道为什么?啊,不,这是突出显示的语法,它将您的awk代码错误识别为带有HLJS强调标记的代码。一个不同的代码标签可以解决这个问题。非常感谢@MartijnPieters,我以前从未在代码标签中使用过
none