以下を含む文字列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
答え1
POSIXの定義長さinは、awk
パラメータを文字列として含む文字列関数です。配列を引数として使用することは、指定されていlength
ない動作です。
いくつかのawk
同様の実装ではgawk (バージョン >= 3.1.6)、AWKのOS Xバージョン、配列を引数として使用でき、length
配列の要素数を返します。
の配列はawk
連想配列であり、連想配列による反復は順序を保証しません。この場合、以下を使用できます。分ける配列の要素数を取得するためにフィールド数を返す関数です。
POSIXlyでは、次のことを試すことができます。
$ 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
答え2
(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
関連配列があります。 〜のようにグレイモア awk チュートリアル 説明する:
特に、連想配列を使用する場合、小さな問題があります。~のため各要素の出力コマンド:出力順序を制御できません。
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 拡張は文書化されています。ここ。
答え3
awk
これらの簡単な作業にこれらの強力なツールを使用するにはかなりのオーバーヘッドがあります。
tstArr2='3,5,8'
tail -n+2 testUnix3.txt | cut -d' ' -f"$tstArr2"