以下のコードをforループを使用して実装していますが、スクリプトの実行後に誤った出力が表示されます。
for i in `awk -F"|" '{print $1}' $INPUTFILE`, j in `awk -F"|" '{print $2}' $INPUTFILE`
do
echo $i:$j
done
シェルスクリプトの単一のforループで複数の変数を使用するのを手伝ってください。
bashは複数の変数を持つループを許可しますが、Cのような構文でのみ可能です。
for ((i=0,j=10;i<=j;i++,j--))
do
echo "i=$i"
echo "j=$j"
done
多分あなたは実際に欲しい:
while IFS='|' read -r i j rest <&3; do
{
printf '%s\n' "something with $i and $j"
} 3<&-
done 3< "$INPUTFILE"
しかし、 Shellループを使用してテキストを処理することは、多くの場合、間違った方法です 。
ここでは、必要なように聞こえます:
awk -F '|' '{print $1 ":" $2}' < "$INPUTFILE"
タイトルの質問への回答として、for
ループが複数の変数を取得するシェルの場合、zsh
が得られます(引用符を付けないことで、すでにzsh構文を使用しているようです)変数、またはコマンド置換を分割するときにグロビングを無効にしない):
$ for i j in {1..6}; do echo $i:$j; done
1:2
3:4
5:6
または短い形式:
for i j ({1..6}) echo $i:$j
POSIXシェルと同等:
set -- 1 2 3 4 5 6
## or:
# IFS='
# ' # split on newline
# set -f # disable globbing
# set -- $(awk ...) # split the output of awk or other command
while [ "$#" -gt 0 ]; do
echo "$1:$2"
shift 2
done
ファイルの出力を変数に格納して、それを2つに分割できます。例:
in exampleファイルの内容は次のとおりです。
a:1
b:2
c:3
d:4
今スクリプト。
#!/bin/bash
for n in $(cat example)
do
first=$(echo $n | cut -d ":" -f 1)
second=$(echo $n | cut -d ":" -f 2)
echo $first
echo $second
done
組み込みシステムでは、何が利用可能であるかが足りないことがよくあります。例えば。 for
は1つの変数のみを持つことができます。 awk
&printf
は単に利用できません。またはIFS
はサポートされていません。等.
これらの状況では、次のような目標を達成できます。
export i=xxx
for j in `cat INPUTFILE` ; do \
[ $i == xxx ] && export i=$j && continue ; \
echo "$i:$j" ; \
export i=xxx ; \
done
unset i
このソリューションのより一般的な形式は次のようになります。
export A=xxx
export B=xxx
for i in 1 2 3 4 5 6 7 8 9 10 11 ; do \
[ $A == xxx ] && export A=$i && continue ; \
[ $B == xxx ] && export B=$i && continue ; \
echo "$A:$B:$i" ; \
export A=xxx ; \
export B=xxx ; \
done
unset A
unset B
export C=$i
役立つ場合はecho
の直前。多くの場合、GNU Parallelはこの解決策となります。
parallel -a $INPUTFILE --colsep '|' echo {1}:{2}
_for i in 1 2 3; do for j in a b c; do ...; done; done
_のように複数の変数を反復処理する場合は、複数のループが必要です。繰り返す対象のリストが別のコマンドの出力である場合、その別のコマンドを$()
でラップする必要があります。