forループ内のawkコマンド

forループ内のawkコマンド

awkループ内でコマンドを試しましたが、成功しませんでしたfor

データを取得するために切り取るために使用する一連の文字列を含む変数がありますawk

どうすればよいかはわかりますが、私が本当に欲しいのは、データを切り捨て続けることです。

だから私はこの変数を持っています:

var="data1,data2,data3"

私は今ここにいる:

for ((i=1; i<=3; i++))
do
    echo $(awk -F, '{print $1}' <<< $var)
done

$1ループに置き換えようとしましたが、$i成功しませんでした。

答え1

二重引用符を使用してawkスクリプトにシェル変数を挿入すると、必要なものを取得できます。それでもリテラルを維持したい場合は、$バックスラッシュを使用してエスケープします。

echo $(awk -F, "{print \$$i}" <<<$var)

これは各反復ごとに、およびを拡張するため、$iawkは、およびを表示し、これによりすべてのフィールドが拡張されます。123$1$2$3

別の可能性は、次のフラグを使用してシェル変数をawk変数に注入することです-v

echo $(awk -F, -v i="$i" '{print $i}' <<<$var)

awk変数の割り当て同じ名前のシェル変数の内容に。 awkの変数はaを使用せず、フィールド用であるため、$参照$iするのに十分です。- 最初のフィールドの場合awkの変数です。

awk 変数に値を代入するのは-v通常、より安全なアプローチです。特に、任意の文字シーケンスを含めることができる場合、コンテンツが意図とは対照的に awk コードで実行されるリスクは少なくなります。しかし、あなたの場合、変数は単一の整数を保持するので、心配しないでください。

for別のオプションは、awk自体内でループを使用することです。これを行う方法の詳細については、awkのドキュメントを参照するか、このサイトを検索してください。

答え2

この場合、使用が多すぎるようです。したがって、awkwhileループを使用するのはどうですか?tr

tr , '\n' <<<"$var" | while read; do
  echo $REPLY
done

出力:

data1
data2
data3

答え3

#!/bin/sh

var='data1,data2,data3'

unset data
while [ "$var" != "$data" ]; do
    data=${var%%,*}    # delete first comma and the bit after it
    var=${var#*,}      # delete bit up to first comma (and the comma)

    printf 'data = "%s"\n' "$data"
done

ここでは、変数置換を使用して、変数値から各連続するカンマ区切りデータフィールドを取得しますvardataループの最初の割り当ては、$var最初のコンマの後のすべての内容を削除します。次に、var最初のカンマの前の最初の数字が削除されるように変数を変更します。

"$var" = "$data"これは、文字列に対して何も実行できないことを意味するまで続きます。

このアプローチを使用すると、新しい行を含むコンマで区切られたデータ文字列を処理できます。

var='line1
line2,data2,last bit
goes here'

上記の値を使用すると、上記のスクリプトがvar出力されます。

data = "line1
line2"
data = "data2"
data = "last bit
goes here"

挿入された改行文字は気にしません。珍しいループから呼び出す必要がありますawk

awk文字列をカンマで区切られたフィールドのセットとして読み取るのはとても良いです。そのフィールドを繰り返すことができます。

printf '%s\n' "$var" |
awk -F ',' '{ for (i=1; i<=NF; i++) print $i }'

を使用するとvar='data1,data2,data3'印刷されます。

data1
data2
data3

別のシェルソリューションは、IFS変数を利用して$var値をビットに分割し、set -fファイル名拡張も無効にします。

set -f
oldIFS=$IFS; IFS=','

set -- $var

IFS=$oldIFS; unset oldIFS
set +f

for data do
    printf 'data = "%s"\n' "$data"
done

答え4

j(変数として)および$j(フィールドインデックスとして)以下を許可します。

for i in 1 2 3; do echo "$var" | awk -v j=$i -F , '{print $j}'; done

$i例では、どちらもプレフィックスとして参照されるawkため、どちらを使用するか(シェルまたは独自の変数 - 優先順位)「混乱しています」。$

ノート

「ポータブル」スクリプト標準であるシェルは、以下をサポートしていません。

(( i=1; i<=3; i++; ))そして<<< $varビルド

ループseq内でコマンドを使用して、for数値シーケンスの生成をより効果的に制御することもできます(使用可能な場合)。

関連情報