나는 다음 gawk
명령을 시도했습니다.
# gawk 'BEGIN{
> var["a"] = 1
> var["g"] = 2
> var["m"] = 3
> var["u"] = 4
> asort(var, test)
> for (i in test)
> print "Index:",i," - value:",test[i]
> }'
다음과 같은 출력을 얻게 됩니다:
인덱스: 4 - 값: 4
인덱스: 1 - 값: 1
인덱스: 2 - 값: 2
인덱스: 3 - 값: 3
그래서 출력이 다음과 같은 순서로 되지 않는 이유가 궁금합니다.
색인: 1
색인: 2
...
이는 배열 값의 올바른 순서이기 때문입니다.
답변1
for (var in array)
배열 요소에 액세스하는 순서 는 보장 되지 않습니다 .
루프는 메모리에 저장된 각 요소를 반복하지만, 다음 요소를 저장하는 동안 awk가 메모리에 구멍을 삽입하기로 결정하면 "이상한" 순서가 발생합니다.
그런데 이것은 공식 문서에 설명되어 있습니다. https://www.gnu.org/software/gawk/manual/html_node/Scanning-an-Array.html#index-for-statement-1
따라서 보장된 정렬 배열을 원한다면 다음과 같은 방법을 사용해야 합니다.
element_count = asort(var, test)
for (i=1; i<=element_count; i++)
print "Index:",i," - value:",test[i]
답변2
asort()
인덱스를 1로 대체하기 때문에 정수로 인덱스된 배열에 더 적합하다고 생각합니다.N, 원래 인덱스를 삭제합니다. (이 사례에서 볼 수 있듯이 인덱스 a
, g
, m
, u
가 누락되었습니다.)
따라서 정수 인덱스 배열의 경우:
$ cat sort.awk
BEGIN {
printf("original:\n");
n = split("hello and bye", a)
for (i = 1; i <= n; i++) {
printf("%d %s\n", i, a[i])
}
printf("sorted:\n");
n = asort(a, b);
for (i = 1; i <= n; i++) {
printf("%d %s\n", i, b[i])
}
}
$ awk -f sort
original:
1 hello
2 and
3 bye
sorted:
1 and
2 bye
3 hello
인덱스에 데이터 자체가 포함되어 있으면 다음과 같이 할 수 있습니다 asorti()
. 원래 키를 값으로 사용하고 키가 순서대로 정렬되도록 1부터 인덱스를 사용하여 새 배열을 만듭니다.
$ cat sort2.awk
BEGIN {
d["foo"]=11;
d["bar"]=22;
d["doo"]=33;
n = asorti(d, p);
for (i = 1; i <= n; i++) {
printf("%d %s %s\n", i, p[i], d[p[i]])
}
}
$ awk -f sort2.awk
1 bar 22
2 doo 33
3 foo 11
두 경우 모두에 설명된 문제는흰부엉이의 대답배열 반복을 고려해야 합니다.