使用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
。