FORループ:ファイルから同時に2つの変数を渡す

FORループ:ファイルから同時に2つの変数を渡す

ファイルから2つの変数を抽出するシェルスクリプトを作成しており、以下のFORループを使用しました。

for i j in `cat list`
                do
                echo title
                echo total "$i" "," "$j"
                echo end
done

猫のリストどこか

AAA 111
BBB 222
CCC 333

予期しない「j」エラーが発生しました。 「whileループ」を使用しましたが、運がありませんでした。

予想される出力は次のとおりです。

title
total AAA,111
total BBB,222
total CCC,333
end

答え1

for実際にもループも必要ありません。while次のいずれかのコマンドがawk機能します。

awk 'BEGIN {print "title"}
           {print "total",$1","$2}
       END {print "end"}' list

または:

awk 'BEGIN {print "title"}
           {printf "total %s,%s\n", $1, $2}
       END {print "end"}' list

ファイルのデータを読み取る前に、BEGIN{print "title"}単語を一度印刷します。title

{print "total",$1","$2}total列の値の間のスペースを表す引用符のないカンマの後に単語を印刷し、列自体を印刷します。このブロックは各入力行に対して実行されます。

END{print "end"}endファイルの単語と終わりを印刷します。 END はファイルから最終入力を読み取った後、ブロックを実行するよう指示します。

2番目のコマンドの場合:

唯一の違いは次のとおりです。

{printf "total %s,%s\n", $1, $2}

これは、型が定義されている場所のprintf代わりにprint最初のパラメータを使用します。

%s,%sとの値をカンマで区切って印刷し、次の行に移動する$1には、新しい行を表し、ファイルの最後までとの値を印刷するように指示します。$2\n$1$2

個人的には、引用符とコンマのprintf両方を使用するのではなく、単一の引用符セットのみを使用できるため、2番目のコマンドを使用します。totalまた、マニュアルページを読んでみるとわかるように、さらにモジュール化されています。 2つの異なる方法を示すために、2つのコマンドのみを含めました。

出力

title
total AAA,111
total BBB,222
total CCC,333
end

答え2

あなたはそれを使用することができますwhile read

echo "title"
while read -r i j
do
    echo total "$i,$j"
done < list
echo "end"

出力は次のとおりです。

title
total AAA,111
total BBB,222
total CCC,333
end

答え3

特定の問題は、テキスト処理ユーティリティを使用するとよりよく解決することができますが、awk@Nasirが示したように(あなたも見ることができますシェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?) タイトルの質問にお答えします。

構文はfor i j in words...; do something with $i and $j; doneまだzshサポートされていませんbash

またbash、分割(必要なもの)とワイルドカード(望ましくないもの)`cmd`(変換したい古いコマンドの代替形式$(cmd))を実行し、zsh期待どおりに分割します。

bash別のPOSIX様シェルを使用して一度に2つの単語を処理するには、for i j in words...次のようにします。

set -- words...
while [ "$#" -gt 0 ]; do
  i=$1 j=$2 # or j=${2-missing}
  something with "$i" and "$j"
  shift "$(( 2 - ($# == 1) ))"
done

あなたの場合はset次のとおりです。

set -o noglob # disable globbing
set -- $(cat list)

(修正がないと仮定すると、デフォルトでは$IFSスペース、タブ、改行が含まれます)。

関連情報