私は各ループで単語を取得しようとしています。i
に挿入する方法がわかりませんprint $2
。
while [ $i -lt 4 ]
do
A=$(awk -F_ '{print $2}' <<< 'one_two_test_three')
echo $A
done
明らかに、これは次のように出力されます。
two
two
two
two
私が望むもの:
one
two
test
three
私は試した:
A=$(awk -F_ '{print $($i)}' <<< 'one_two_test_three')
役に立たない。
答え1
正しい方法は、()オプションを使用してbash/shell
変数をawk
引数としてスクリプトに渡すことです。-v
variable
i=1;
while [ $i -lt 5 ]; do
A=$(awk -v i="$i" -F_ '{ print $i }' <<< 'one_two_test_three')
echo $A
((i++))
done
出力:
one
two
test
three
答え2
データの解析にシェルループは必要ありません。
$ awk -F '_' '{ for (i=1; i<=NF; ++i) print $i }' <<<'one_two_test_three'
one
two
test
three
スクリプトは入力_
を区切りリストに解析し、各フィールドを印刷します。
短く:
$ awk -F '_' 'BEGIN { OFS="\n" } { $1=$1 } 1' <<< 'one_two_test_three'
one
two
test
three
これは、出力フィールドの区切り文字を改行文字に設定し、レコードを印刷する前にレコード全体を強制的に再構成(新しい区切り文字を挿入)するようにします。
短く:
$ tr '_' '\n' <<<'one_two_test_three'
one
two
test
three
データによるループ:
tr '_' '\n' <<<'one_two_test_three' |
while read -r word; do
printf 'Got "%s"\n' "$word"
done
これにより、データを複数回解析するために使用されるユーティリティは呼び出されません。
答え3
値に改行文字がないと仮定すると、次のようになります。コードが機能するには最小限の変更が必要です。を#!/bin/bash
使用しているので、shebangは(kshまたはzsh)でなければなりません<<<
。
i=1
while [ "$i" -le 4 ]
do
A=$(awk -v var="$i" -F_ '{print $var}' <<< 'one_two_test_three')
echo "$A"
i=$((i+1))
done
ただし、文字列はシェルから出てくるので、次のように単純化できます。
IFS=_ read v1 v2 v3 v4 <<<'one_two_test_three'
printf '%s\n' "$v1" "$v2" "$v3" "$v4"
そして、値の配列(可変数の値)を使用します。
#!/bin/bash
IFS=_ read -a v <<<'one_two_test_three'
printf '%s\n' "${v[@]}"
より単純なシェルを使用する必要がある場合:
#!/bin/sh
IFS=_ read v1 v2 v3 v4 <<-_expandvar_
one_two_test_three
_expandvar_
printf '%s\n' "$v1" "$v2" "$v3" "$v4"
もちろん、変数を設定する必要がない限り、スクリプトでIFS値を設定するのに問題はありません。
#/bin/sh
a='one_two_test_three'
IFS=_
set -f
printf '%s\n' $a
この変数は引用符なしで使用されるため、安全ではない可能性があります。