1

複数の列のデータを含むファイルを読み取り、2 番目の列の各値を 3 番目の列の各値で乗算し、これらすべての乗算の結果を加算する Bash スクリプトを作成しようとしています。

たとえば、ファイルが次のようになっているとします。

Column 1    Column 2    Column 3    Column 4
genome      1           30          500
genome      2           27          500
genome      3           83          500
...

スクリプトは 1*30 を掛けて 30 にし、次に 2*27 を掛けて 54 (そしてそれを 30 に足す)、次に 3*83 を掛けて 249 (そしてそれを 84 に足す) など.

awk を使用して入力ファイルを解析しようとしましたが、操作を行ごとに進める方法がわかりません。現在、最初の行が読み取られ、変数に対する操作が実行された後に停止します。

これまでに書いたものは次のとおりです。

for file in fileone filetwo
do
    set -- $(awk '/genome/ {print $2,$3}' $file.hist)
    var1=$1
    var2=$2
    var3=$((var1*var2))
    total=$((total+var3))

    echo var1 \= $var1
    echo var2 \= $var2
    echo var3 \= $var3
    echo total \= $total
done

すべてに「while read」ループを配置しようとしましたが、変数を各行で更新できませんでした。私はこれについて間違った方法で行っていると思います!

私は Linux と Bash のスクリプト作成に非常に慣れていないので、どんな助けでも大歓迎です!

4

2 に答える 2

2

これは、awk がファイル全体を読み取り、各行でプログラムを実行するためです。したがって、得られる出力は次のようにawk '/genome/ {print $2,$3}' $file.histなります

1 30
2 27
3 83

など、つまり、bash スクリプトでは、setコマンドは次の変数の割り当てを行います。

$1 = 1
$2 = 30
$3 = 2
$4 = 27
$5 = 3
$6 = 83

など。ただし、スクリプトでは and のみを使用$1$2ます。つまり、ファイルの残りの内容 (最初の行以降のすべて) は破棄されます。

正直なところ、bash の使い方を学ぶためだけにこれを行っているのでない限り、awk で行うことをお勧めします。awk はファイル内のすべての行に対して自動的に実行されるため、2 列目と 3 列目を簡単に乗算して現在の合計を維持できます。

awk '{ total += $2 * $3 } ENDFILE { print total; total = 0 }' fileone filetwo

ENDFILEこれは、「各行ではなく、各ファイルの最後でこの次のブロックを実行する」ことを意味する特別なアドレスです。

教育目的でこれを行っている場合、これを言わせてください: bash で算術演算を行うことについて知っておく必要がある唯一のことは、bash で算術演算を行うべきではないということだけです:-P 真剣に、数字を操作したい場合、bash はその仕事に最も適していないツールの1つ。しかし、本当に知りたい場合は、これを編集して、主に bash でこのタスクを実行する方法に関する情報を含めることができます。

于 2013-03-15T21:22:36.390 に答える
0

awk一般に、この種の作業により適していることに同意しますが、純粋なbash実装がどのようになるか興味がある場合は、次のようにします。

for f in file1 file2; do
    total=0
    while read -r _ x y _; do
        ((total += x * y))
    done < "$f"
    echo "$total"
done
于 2013-03-15T21:36:35.877 に答える