次の内容の文字列tstArr2があります
'3 5 8'
今awkでフラットファイルを解析したい
test my array which array is better array
INDIA USA SA NZ AUS ARG GER BRA
US AUS INDIA ENG NZ SRI PAK WI BAN NED IRE
これらの番号付きの列でのみ。私は以下を試しました
awk -vA="$tstArr2" 'BEGIN{split(A,B," ");} {if(NR>1){for(i=1; i<= length(B); i++){printf "%s ",B[i]}}print " "}' testUnix3.txt
しかし、それは言います
awk: Cannot read the value of B. It is an array name.
The input line number is 2. The file is testUnix3.txt.
The source line number is 1.
何が足りないのですか?次のことを試してみると
awk -vA="$tstArr2" 'BEGIN{split(A,B," ");} {if(NR>1){for(i in B){printf "%s ",$B[i]}}print " "}' testUnix3.txt
出力を出力しますが、順序が正しくありません。私はそれらを整然とさせたい。説明してください。必要な出力:
SA AUS BRA
INDIA NZ WI
POSIX定義 length in awk
は文字列関数であり、引数は文字列と見なされます。配列を引数としてlength
を使用することは、不特定の動作です。
gawk(バージョン> = 3.1.6) 、 OS XバージョンのAWK のようなawk
の一部の実装では、length
を使用できます。配列を引数として使用すると、配列内の要素の数が返されます。
awk
の配列は連想配列であり、連想配列をループすることは順序について何も保証しません。この場合、 split 関数を利用できます。この関数は、フィールドの数を返し、配列の要素の数を取得します。
おそらく、あなたは試すことができます:
$ awk -vA="$tstArr2" '
BEGIN{n = split(A,B," ");}
{
if(NR > 1) {
for(i = 1;i <= n;i++) {
printf "%s ",$B[i];
}
}
print " ";
}
' file
SA AUS BRA
INDIA NZ WI
(GNU以外のawkについては、@ cuonglmの回答を参照してください。)
これをテストファイルとして:
_$ cat testUnix3.txt
test my array which array is better array
INDIA USA SA NZ AUS ARG GER BRA
US AUS INDIA ENG NZ SRI PAK WI BAN NED IRE
_
このコードは、列3、5、および8を選択します。
_$ tstArr2='3 5 8'
$ awk -vA="$tstArr2" 'BEGIN{split(A,B," ");} NR>1{for(i=1; i<= length(B); i++) printf "%s ",$B[i]; print "";}' testUnix3.txt
SA AUS BRA
INDIA NZ WI
_
上記はGNU awk
でテストされました。
awk
ループと順序awk
には連想配列があります。 Grymoire awkチュートリアル が説明するように:
特に連想配列を使用する場合、連想配列には1つの小さな問題があります。 for 各要素を出力するコマンド:出力の順序を制御することはできません。
これが、for(i in B)
ループを使用する、引用した他のコードが列を順不同で出力する場合がある理由です。
GNU awkには、この問題を克服するための拡張機能があります。
_$ gawk -vA="$tstArr2" 'BEGIN{split(A,B," "); PROCINFO["sorted_in"]="@ind_num_asc"} {if(NR>1){for(i in B){printf "%s ",$B[i]}print " "}}' testUnix3.txt
SA AUS BRA
INDIA NZ WI
_
_PROCINFO["sorted_in"]="@ind_num_asc"
_を設定すると、インデックスは数値の昇順でループされます。このGNU拡張子は文書化されています ここ 。
このような単純なタスクにawk
のような強力な機器を使用するには、多くのオーバーヘッドがあります。
tstArr2='3,5,8'
tail -n+2 testUnix3.txt | cut -d' ' -f"$tstArr2"