web-dev-qa-db-ja.com

awkとbashを使用して配列を初期化する方法は?

テキストファイルの最初の行の値を配列に格納しようとしています。これが私がこれまでに持っているものです:

arr_values=()

awk '
    NR==1 {
            for (i=0; i<=NF; i++)
               'arr_values[i]'=$i            #error here
          }' file.txt

for ((i=0; i<${#arr_values[@]}; i++))
do
   echo ${arr_values[i]}
done

awkを使用して外部配列を初期化する方法がわからないため、配列の初期化でエラーが発生します。何か提案はありますか(awkのみ)?ありがとう。

クロスポストをお詫びします。希望する答えが得られませんでした。

2
Redson

awkを使用する場合は、次のように実行できます。

arr_values=( $(awk '{print;exit}' file) )

シェルは空白で分割を行います。行にワイルドカードが含まれている場合、それらは一致するファイルのリストに展開されることに注意してください(存在する場合)。使用する set -fワイルドカード展開を無効にします。

set -f
arr_values=( $(awk '{print;exit}' file) )
set +f
2
cuonglm

この方法で正確に行うことはできません。 awkコマンドを実行させ、区切り文字(スペース、タブ、NULなど)で区切られた一連の出力値を作成してから、これらを配列要素に割り当てる必要があります。これは、awkがシェルによって実行されるプログラムであり、anyより多くのシェル操作が実行される前に完了するまで実行されるためです。このようなawkのものにShellのものを埋め込むことはできません。

以下のようなことで簡単な例を使用できますが、指定したawkコードがどのような場合でも希望どおりに機能するかどうかはわかりません。ファイルにゼロレコードまたは複数のレコードがある場合、出力(したがって、シェル配列)にはファイルの行が含まれます。出力配列に、ゼロからファイル内にあるフィールドの数までの整数のセットを含めたいようです。これは、レコードが1つしかない場合に限ります。より大きなファイルが配列に表示されないようにしたい場合は、以下で行ったように、アクションとして「{}」のみを含む2番目のパターンレスアクションをawkコードに追加する必要があります。また、ファイル名のワイルドカード展開をオフにします(set -f)行にワイルドカード文字が含まれている場合\[*?

set -f
arr_values=(`awk '
    NR==1 {
            for (i=0; i<=NF; i++)
               print $i
          }

          { }' file.txt`)
set +f
for ((i=0; i<${#arr_values[@]}; i++))
do
   echo "${arr_values[i]}"
done
2
Alan Mimms

whyawk...と、データの最初の行がどのように見えるかについてコンテキストを説明すると、より良い答えが得られる可能性があります。

フィールド区切り文字を変更していないので、スペースで区切られた項目の行を処理していると想定しています。以下はあなたが探していることを正確に行います:

arr_values=()

read -ra arr_values <<< $(head -n 1 file.txt)

for s in "${arr_values[@]}"; do
    echo "$s"
done

すべての作業はreadコマンドで実行されます。配列内の値を複数回処理する必要がない限り、次に、次のことを簡単に行うことができます。

set -f    # disable globbing, in case the lines contain wildcard characters
for s in $(head -n 1 file.txt); do
    set +f
    echo "$s"
done
set +f

これにより、空白で区切られた空白以外の各フィールドエントリが$sに配置され、ループを1回通過します。

2
user73383

他のことについてはわかりませんが、空白で分割している場合、これにより、テキストファイルの最初の行が空白で分割されたシェル配列に格納されます。

set -f ; set -- $(head -n1 <textfile) ; set +f

必要なのはそれだけです。これで、位置パラメータはさまざまな配列インデックスになり、配列は"$@"になります。

0
mikeserv