linux Shellスクリプトの中で一つの配列をawk内部に伝達して処理します。

1464 ワード

先日何人かの同僚と一つの問題を討論しました。シェルシナリオの中でどのように一つの配列をawk内部に伝達して処理しますか?
その時は方法が見つからなかった。先日QQグループでawkのことを話していたら、ついまたこの話をしてしまいました。機縁があって一つの考えを見つけました。ここで共有します。
テスト環境:

[root]# head -1 /etc/redhat-release
Red Hat Enterprise Linux Server release 6.5 (Santiago)
[root]# awk --version | head -1
GNU Awk 3.1.7
ご存知のように、Shellスクリプトの中で普通変数をawkに渡すのはとても簡単です。直接に-vパラメータの割り当てをすればいいです。

str1="Hello World"
awk -v str2="$str1" 'BEGIN{print str2}'
しかし、行列をawkに渡すのは簡単なことではない。次の三つのテストを見てください。
1.簡単な配列は先に値を付けられます。

arr1=(A B C)
awk -v arr2="${arr1[*]}" 'BEGIN{split(arr2,arr3," "); print arr3[2]}'
2.適切なセパレータを見つけにくい場合があります。特定の配列要素にはセパレータとして使用したい文字が含まれている可能性があります。この場合、スプリット以降は希望の結果が得られません。したがって、この方法は厳密ではなく、特に配列要素がどの文字を含むか予測できない場合があります。

arr1=(A "B C" D)
awk -v arr2="${arr1[*]}" 'BEGIN{split(arr2,arr3," "); print arr3[2]}'
3.exportコマンドとawkのENVIRONデフォルト配列によってこの機能を実現できます。

arr1=(A "B C" D)
for((i=0;i<${#arr1[*]};i++)); do
   export arr1_m$i="${arr1[$i]}"
done
awk 'BEGIN{for(i in ENVIRON)if(i~/arr1_m/)print i "=" ENVIRON[i]}'
ここではデモンストレーション機能のためだけに、export変数名の定義とawk内部の文字列を一致させて書くという特別なこだわりはありません。実際の状況によって調整できます。
結論:Shellスクリプトの中で一つの配列をawk内部に伝達して処理します。技術的には可能ですが、生産環境での使用は勧められません。