私はawk
スクリプト内でbash
を使用して、かなり一般的なタスクを実行しようとしています。適切に構造化されたファイル行を反復処理し、区切り文字で配列に分割します。ファイルのサンプルは次のとおりです。
Joe:Johnson:25
Sue:Miller:27
対話モードでこれを1行で行う方法の例は多数ありますが、bash自体のawkサブシェルの外でawkによって操作される配列を使用したいスクリプトで実行しています。
cat ${smryfile} | while read smryline; do
echo ${smryline}
#now i want to split the line into array 'linearray' in awk but have it usable when i get back to bash
echo ${smryline} | awk '{split($0,$linearray,":")}'
varX=$linearray[2]
echo $varX
#do something with $varX
done
エラーが発生します:
awk: syntax error at source line 1
context is
>>> {split($0,$linearray <<< ,":")}
awk: illegal statement at source line 1
私がやろうとしていること(スコープ外のawkで定義されている配列を使用)を実行することは可能ですか?
私はあなたがawkなしであなたが望むことをすることができると思います:
cat "${smryfile}" | while IFS=: read first last varx
do
echo "first='$first' last='$last' varx='$varx'"
# do something
done
これにより、以下が生成されます。
first='Joe' last='Johnson' varx='25'
first='Sue' last='Miller' varx='27'
この方法は、ファイル内の名前にスペースが含まれている場合でも機能することに注意してください。
上記のcat
を使用する必要がないことにも注意してください。
while IFS=: read first last varx
do
echo "first='$first' last='$last' varx='$varx'"
# do something
done <"${smryfile}"
上記のようにcat
を削除することの副次的な利点は、ループで作成した変数がループの終了後も存続することです。
これはうまくいくはずです:
linearray=($(awk -F: '{$1=$1} 1' <<<"${smryline}"))
echo ${linearray[2]}
# output: 27
説明:awk -F:
は:
の入力を分割します。 awk
はデフォルトで、変更された出力をスペースで区切るため、awk
からの出力を使用してbash配列を直接作成できます。注変更された出力、つまり$1=$1
へのno-op呼び出し。それ以外の場合、データは元の形式で出力されます。
しかし、例を挙げれば、awk -F:
を使用して3番目の列を抽出し、出力をループしないでください。
awk -F: '{print $3}' "$smryfile" | while read varX; do
echo $varX
done
あなたがawk
で解決策を求めたのは確かですが、sed
解決策はもう少し明確だと思います。
str="Joe:Johnson:25"
array=($(echo "$str" | sed 's/:/ /g'))
for el in "${array[@]}"; do
echo "el = $el"
done
これは与える:
el = Joe
el = Johnson
el = 25
この場合、コマンド展開を二重引用符で囲まないようにする必要があります。そのため、単一の文字列要素で終わることはありません。
もちろん、これはスペースを含む要素では機能しません。あなたが持っていた場合:
str="Joe:Johnson:25:Red Blue"
あなたは終わるだろう
el = Joe
el = Johnson
el = Red
el = Blue
ただし、eval
を使用してもかまわない場合は、配列割り当ての前に引用符を挿入して機能させることができます。
eval "array=($(echo "\"$str\"" | sed 's/:/" "/g'))"
# Before the eval, it turns into:
eval "array=("Joe" "Johnson" "25" "Red Blue")"