2つのファイル間の算術演算により、一連の新しいファイルが生成されます。

2つのファイル間の算術演算により、一連の新しいファイルが生成されます。

次のような統合分析形式に変更したいタブ区切りのモデル入力ファイルがあります。

入力.txt

/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.5
abies_grandis 2.5 0.4
larix_occidentalis 1.5 0.3

次のように、1行に1つずつ別の乗数ファイルがあります。

乗数.txt

0.5
0.6
0.7

あるフィールド(wsg)に2番目のファイルの単一の乗数を掛ける一連の新しい入力ファイルを作成したいと思います。この例では、3つの乗数に対応する3つの新しいファイルがあります。出力ファイルは次のとおりです。

ファイル1.txt(wsg * 0.5)

/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.25
abies_grandis 2.5 0.2
larix_occidentalis 1.5 0.15

ファイル2.txt(wsg * 0.6)

/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.3
abies_grandis 2.5 0.24
larix_occidentalis 1.5 0.18

ファイル3.txt(wsg * 0.7)

/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.35
abies_grandis 2.5 0.28
larix_occidentalis 1.5 0.21

これはawkとforループを使用して可能なようですが、これを行うのに必要なレベルまでawkを知りません。この問題にどのように対処する必要がありますか?

ベストアンサー1

現在持っている乗数に関係なく、すべてのUnixシステムのすべてのシェルでawkを使用してください。

$ ls *.txt
input.txt  multipliers.txt

$ cat tst.awk
NR==FNR {
    if ( pastHdr ) {
        ++numLines
        wsg[numLines] = $NF
        sub(/[[:space:]][^[:space:]]+$/,"")
        rest[numLines] = $0
    }
    else {
        hdr = hdr $0 ORS
        if ( $1 == "***" ) {
            pastHdr = 1
        }
    }
    next
}
{
    out = "file" FNR ".txt"
    printf "%s", hdr > out
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        print rest[lineNr], wsg[lineNr] * $0 > out
    }
    close(out)
}

$ awk -f tst.awk input.txt multipliers.txt

$ ls *.txt
file1.txt  file2.txt  file3.txt  input.txt  multipliers.txt

$ head file*.txt
==> file1.txt <==
/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.25
abies_grandis 2.5 0.2
larix_occidentalis 1.5 0.15

==> file2.txt <==
/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.3
abies_grandis 2.5 0.24
larix_occidentalis 1.5 0.18

==> file3.txt <==
/* Preciptation in mm */
10 30 40 50 23

### Species description
*** sp_name LMA wsg
abies_lasiocarpa 2 0.35
abies_grandis 2.5 0.28
larix_occidentalis 1.5 0.21

上記は非常に似ています。@guest_7が投稿したソリューション、私がこの記事を投稿する理由は次のとおりです。

  1. 多くの単一文字変数名を使用すると、IMHOこのサイズのスクリプトは初心者が理解するのが難しくなります。
  2. wsg値を削除しますNF--が、NFを減らすことは未定義の動作であるため、移植性はありません。
  3. ヘッダーの行数をハードコードします。 (これは間違っていないかもしれません。テキストを解析して決定することは私が好むものですが、実際の入力が常に投稿された例と同じかどうかによって間違っている可能性があります。そうでない場合は何ですか?違い)。

おすすめ記事