テキスト ファイルの最初の行の値を配列に格納しようとしています。 これまでのところ、次のようになっています。
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
? よろしくお願いします。
クロスポストして申し訳ありません。望んでいた回答が得られませんでした。
答え1
文脈を説明していただければ、より良い回答が得られるかもしれません。なぜ awk
...そして、データの最初の行は次のようになります。
フィールド区切りを変更していないので、スペースで区切られた項目の行を処理していると想定しています。次の操作は、まさに目的の動作を実行します。
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
正確にこの方法ではできません。awkコマンドを実行して、何らかの区切り文字(スペース、タブ、NULなど)で区切られた一連の出力値を作成し、それを配列要素に割り当てる必要があります。その理由は、awkはシェルによって実行されるプログラムであり、完了するまで実行してからどれでもより多くのシェル操作が実行されます。このように awk の中にシェルのものを埋め込むことはできません。
簡単な例を使用するには、以下のようにすることができますが、提供した awk コードがいずれの場合でも必要な動作をするかどうかはわかりません。ファイルにレコードが 0 個または複数個ある場合、出力 (およびシェル配列) にはファイルの行が含まれます。ファイルにレコードが 1 個しかない場合に限り、出力配列に 0 からファイル内のフィールド数までの整数のセットを含めたいようです。配列に大きなファイルが表示されないようにするには、以下に示すように、アクションとして "{ }" のみを含む 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
答え3
を使用したい場合はawk
、次のようにします。
arr_values=( $(awk '{print;exit}' file) )
シェルは空白で分割します。行にワイルドカードが含まれている場合、一致するファイルのリスト(存在する場合)に拡張されることに注意してください。set -f
ワイルドカード拡張を無効にするには、を使用します。
set -f
arr_values=( $(awk '{print;exit}' file) )
set +f
答え4
他のことはわかりませんが、空白で分割する場合、テキスト ファイルの最初の行が、空白で分割されたシェル配列に格納されます。
set -f ; set -- $(head -n1 <textfile) ; set +f
必要なのはこれだけです。これで、位置パラメータはさまざまな配列インデックスになり、配列は になります"$@"
。