我的文件fruit
包含以下内容:
Apples, 12
Pears, 50
Cheries, 7
Strawberries, 36
Oranges, 2
我想对文件的数字数据进行排序:
for(i=1;i<=NF;i++)j+=$i;printf "Fruit %d%s, %d\n",NR,OFS,$1,j | sort -k 2 > "numbers"; j=0"
为了运行 awk 脚本,我运行命令:
awk -f numbers fruit
数字文件的内容与水果相同,但其第一个和第二个字段被复制到数字文件中。
答案1
GNU awk 为您提供了一种巧妙的方法来控制如何遍历数组:请参阅控制数组遍历和控制扫描
gawk -F', ' '
{fruit[$1] = $2}
END {
OFS = FS
printf "\nordered by fruit name\n"
PROCINFO["sorted_in"] = "@ind_str_asc"
for (f in fruit) print f, fruit[f]
printf "\nordered by number\n"
PROCINFO["sorted_in"] = "@val_num_desc"
for (f in fruit) print f, fruit[f]
}
' fruit
输出
ordered by fruit name
Apples, 12
Cheries, 7
Oranges, 2
Pears, 50
Strawberries, 36
ordered by number
Pears, 50
Strawberries, 36
Apples, 12
Cheries, 7
Oranges, 2
答案2
print
您实际上可以传递awk "sort"
(注意引号):
$ awk '{print "Fruit",NR, $0 | "sort -k 2 -t, -rn"}' fruit
Fruit 2 Pears, 50
Fruit 4 Strawberries, 36
Fruit 1 Apples, 12
Fruit 3 Cheries, 7
Fruit 5 Oranges, 2
因此,要写信给numbers
,您可以执行以下操作:
awk '{print "Fruit",NR, $0 | "sort -k 2 -t, -rn > numbers"}' fruit
请注意,我稍微简化了您的 awk。无需printf
在此处使用或显式打印,OFS
因为您不会在任何地方更改它。我也不明白你for(i=1;i<=NF;i++)j+=$i
在做什么。您已经拥有该号码NR
,但您printf
并没有使用j
。
答案3
我在 2002 年肯定遇到了 SunOS nawk 的严重问题。我发现我的测试脚本包含三个在非 GNU awk 中运行的 awk 实现:
(a) eSort:使用工作文件并通过运行排序命令的管道读回。就我而言,情况不太好,因为我通过 ssh 进行无代理监控,而外部工作文件对于我们的实时服务器来说侵入性太大。
(b) qSort:递归分区排序。对于大数据来说性能很差,并且超过 2000 个元素会破坏 mawk 中的堆栈。不过写起来很有趣。
(c) hSort:15 行原位排序算法。该堆使用索引算法来支持二叉树(请参阅维基百科)。
该 bash 脚本包含 awk 函数 hSort 和 hUp,它们实现实际排序。一个操作行将所有输入放入一个数组中,END 块调用 hSort 并报告结果。
输入数据是“man bash”的内容,一次为行,一次为单词。我们使用 wc 来证明没有丢失任何内容,并使用 sort -c 来证明输出已排序。计时包括读取和打印开销。
这是测试镜头:
Paul--) ./hSort
Sorted 5251 elements.
real 0m0.120s
user 0m0.116s
sys 0m0.004s
5251 44463 273728 hSort.raw
sort: hSort.raw:2: disorder:
5251 44463 273728 hSort.srt
Sorted 44463 elements.
real 0m1.336s
user 0m1.316s
sys 0m0.008s
44463 44463 265333 hSort.raw
sort: hSort.raw:3: disorder: Commands
44463 44463 265333 hSort.srt
这是剧本。享受!
#! /bin/bash
export LC_ALL="C"
#### Heapsort algorithm.
function hSort { #:: (void) < text
local AWK='''
#.. Construct the heap, then unfold it.
function hSort (A, Local, n, j, e) {
for (j in A) ++n;
for (j = int (n / 2); j > 0; --j) hUp( j, A[j], n, A);
for (j = n; j > 1; --j) { e = A[j]; A[j] = A[1]; hUp( 1, e, j - 1, A); }
return (0 + n);
}
#.. Given an empty slot and its contents, pull any bigger elements up the tree.
function hUp (j, e, n, V, Local, k) {
while ((k = j + j) <= n) {
if (k + 1 <= n && STX V[k] < STX V[k + 1]) ++k;
if (STX e >= STX V[k]) break;
V[j] = V[k]; j = k;
}
V[j] = e;
}
{ U[++nU] = $0; }
END {
sz = hSort( U);
printf ("\nSorted %s elements.\n", sz) | "cat 1>&2";
for (k = 1; k in U; ++k) print U[k];
}
'''
mawk -f <( printf '%s\n' "${AWK}" )
}
#### Test Package Starts Here.
function Test {
time hSort < hSort.raw > hSort.srt
for fn in hSort.{raw,srt}; do wc "${fn}"; LC_ALL="C" sort -c "${fn}"; done
}
AWK_LINE='{ sub (/^[ \011]+/, ""); print; }'
AWK_WORD='{ for (f = 1; f <= NF; ++f) print $(f); }'
#xxx : > hSort.raw; Test #.. Edge cases.
#xxx echo "Hello" > hSort.raw; Test
#xxx { echo "World"; echo "Hello"; } > hSort.raw; Test
man bash | col -b | mawk "${AWK_LINE}" > hSort.raw; Test
man bash | col -b | mawk "${AWK_WORD}" > hSort.raw; Test