아마도 여기서 아주 간단한 것을 놓치고 있을 수도 있지만,
echo 'The quick brown fox jumped over the lazy dog.' | \
awk '{
split($0, WORDS, " ");
for ( WORD in WORDS ) {
print $WORD;
}
}'
나는 그 대가로 이것을 얻습니다:
quick
brown
fox
jumped
over
the
lazy
dog.
The
첫 번째 단어가 마지막에 인쇄되는 이유는 무엇입니까?
$ awk --version
awk version 20070501
답변1
우선, Yield for (i in array)
에 있는 것은 awk
배열 요소가 아닌 배열의 인덱스입니다. 그래서 당신은 방문한 것과 같은 결과를 얻습니다 $1
. ....$2
$NF
echo 'The quick brown fox jumped over the lazy dog.' | \
awk '{
split($0, WORDS, " ");
for ( WORD in WORDS ) {
print WORD;
}
}'
2
3
4
5
6
7
8
9
1
변수에 액세스하면 배열 인덱스를 얻는 것을 볼 수 있습니다 WORD
.
귀하의 질문에 대해 POSIX는 awk
배열 루핑을 통해 배열 인덱스 생성을 정의합니다.지정된 주문이 없습니다.:
for(배열의 변수)
반복하여 배열의 각 인덱스를 변수에 할당합니다. 지정된 주문이 없습니다..
따라서 정의하는 것은 구현에 달려 있습니다.어떻게배열을 반복합니다.
내 시스템에 대한 빠른 테스트에서는 다음과 같이 증가하는 순서 gawk
로 반복되는 것을 보여줍니다 mawk
.
for AWK in gawk mawk /usr/5bin/[on]awk /usr/5bin/posix/awk; do
printf '==%s==\n' "$AWK"
echo 'The quick brown fox jumped over the lazy dog.' |
"$AWK" '{
split($0, WORDS, " ")
for (WORD in WORDS) {
print WORD;
}
}' | { sed 1q; tail -n1 }
done
==awk==
1
9
==mawk==
1
9
==/usr/5bin/nawk==
2
1
==/usr/5bin/oawk==
2
1
==/usr/5bin/posix/awk==
2
1
(GNU를 사용 sed
하면 sed -u 1q
)
답변2
배열의 요소를 인쇄하는 대신 필드를 순차적으로 인쇄합니다. 에서는 변수 앞에 , 즉 필드가 awk
붙지 않습니다 . $
따라서 $a
필드에 저장된 모든 숫자가 인쇄됩니다 a
. 예를 들어 변수를 인쇄하려면 , no 가 foo
필요합니다 .print foo
$
배열을 반복하면 awk
배열의 인덱스가 반복됩니다.
$ echo 'The quick brown fox jumped over the lazy dog.' | awk '{
split($0, WORDS, " ");
for ( WORD in WORDS ) {
print WORD;
}
}'
1
2
3
4
5
6
7
8
9
당신이 추구하는 것은 다음과 같습니다
$ echo 'The quick brown fox jumped over the lazy dog.' | awk '{
split($0, WORDS, " ");
for ( WORD in WORDS ) {
print WORDS[WORD];
}
}'
The
quick
brown
fox
jumped
over
the
lazy
dog.
GNU에서는 awk
다음과 같습니다.
$ echo 'The quick brown fox jumped over the lazy dog.' | awk '{
for (i=1; i<=NF;i++){
print $i
}
}'
gawk
(GNU awk
)는 split
찾은 순서대로 배열을 정렬 하지만 (위에 표시된 대로), cuonglm이 그의 답변에서 설명하는 것처럼 다른 구현에서는 이를 수행하지 않습니다. 따라서 split
필드 구분 기호를 설정하고 awk
대신 let을 사용하여 분할을 수행할 수 있습니다. 귀하의 예에서는 구분 기호가 공백이므로 필요하지 않지만 다른 경우에는 구분 기호를 사용하는 방법은 다음과 같습니다.
$ echo 'The-quick-brown-fox-jumped-over-the-lazy-dog.' |
awk -F"-" '{
for(i=1;i<=NF;i++){
print $i
}
}'
The
quick
brown
fox
jumped
over
the
lazy
dog.
답변3
$1
$2
귀하의 예에서 각 필드 등 을 인쇄할 수 있다는 사실을 무시하고 split
배열의 요소 수를 반환하므로 표시되는 순서대로 반복하려면 다음과 같이 사용할 수 있습니다.
echo 'The quick brown fox jumped over the lazy dog.' | \
awk '{
n = split($0, WORDS, " ");
for (i = 1; i <= n; ++i) {
print WORDS[i];
}
}'
다른 사람들이 언급했듯이 배열이 탐색되는 순서는 for (indx in array)
사용할 때 지정되지 않습니다(GNU awk를 사용하면 제어할 수 있지만).