forループを使用して両方のファイルを繰り返し、インデックスを評価します。

forループを使用して両方のファイルを繰り返し、インデックスを評価します。

私はbashシェルスクリプトを学んでおり、awkなどではなく純粋なbashメソッドを探しています。

情報に基づいて式を作成できるように、forループを使用して端末にパラメータとして送信された2つのファイルの内容を繰り返すことを試みます。

ファイルの内容はタブで区切られます。このファイルには拡張子がありません。以下は、評価するファイル情報のタイプの例です。

$cat file1
1     2     3
40    50    60

$cat file2
10     20     30
40     50     60

私が書いたコードは次のとおりです。

read line1 < "file1"
read line2 < "file2"

difference=0

#I can see the contents of file1 with the below code and by changing the code
#slightly I can see the contents of file2 as well using the following code:

for index1 in $line1
do
echo "The contents of index1 are: $index1"
done

#But I am trying to do something like this which isn't working:
for index1 in $line1, index2 in $line2
do
difference=$(expr $index1 - $index2)
echo $difference
done

答え1

確かに可能ですが、楽しくありません。実際には、物事に異なるアプローチをしたいと思います。

これらの特定のファイルとこの操作の場合、このスクリプトはおそらく最も単純で、whileループの代わりに単一のループを使用しますfor

exec 3<file2
while read a1 a2 a3 && read b1 b2 b3 <&3
do
    echo $((a1 - b1))
    echo $((a2 - b2))
    echo $((a3 - b3))
done < file1

各ファイルは固定された3列構造で、すべてのファイルを一度に読み込みます。file2ファイル記述子3で開く(exec 3<file2)独立して読むことができますfile1。作成した内容はファイルを開いて読み込みます。最初毎回並んでください。このreadコマンドは最初の単語をにx1、2番目の単語をにx2、残りの行を `x3に入れます。

両方のリストを一緒に「圧着」したり、並列forループを作成したりする組み込みまたは比較的簡単な方法はありません。単純な配列や文字通りの単語リスト以外の項目の for ループは不可能になりにくく、正しい配列を構築するには、他の作業を実行するよりも多くの作業が必要です。


列数が可変であれば、これはより難しいですが、次のものを使用できます。mapfile行から配列を作成し、通常の配列処理を使用します。C型forループ各行に対して、次の操作を行います。

while read line1 && read line2 <&3
do
    mapfile -d $'\t' a1 <<<"$line1"
    mapfile -d $'\t' a2 <<<"$line2"
    for ((i=0; i<${#a1[@]}; i++))
    do
        echo $((a1[i] - a2[i]))
    done
done <file1

a1これにより、次を含む2つの配列がa2作成されます。タブ区切り要素一行に、行の長さだけ繰り返しますfile1(他のファイルの追加項目は無視されます)。

zipファイルの形式が正しく、列番号がその行と一致すると仮定すると、最も一般的な近似は似ていますwhile read a b ... done < <(paste <(printf '%s\n' $(<file1)) <(printf '%s\n' $(<file2)))。これは本当に嫌なことです。


言い換えれば、シェルスクリプトは、このタイプの処理に適したメカニズムではありません。一方、awk(またはより良い場合は適切な言語)は、これよりも適切で壊れやすいです。

上記のスクリプトを見ると、実装が複雑すぎて壊れやすくなり、言語がそのために設計されていないため、従うのが難しいことがわかります。このスクリプトはもっと同じ目標を達成する他の方法よりも読みやすく、特に意味はありません。

関連情報