Shell-Script

生成一系列新文件的 2 個文件之間的算術運算

  • February 13, 2021

我有一個製表符分隔的模型輸入文件,我想改變一個與此類似的集成分析

輸入.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

我有另一個乘法器文件,每行一個,例如

乘數.txt

0.5
0.6
0.7

我想生成一系列新的輸入文件,其中一個欄位(wsg)乘以第二個文件中的單個乘數。在此範例中,將有 3 個新文件對應於 3 個乘數。輸出文件如下所示:

file1.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

file2.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 的了解還沒有達到執行此任務所需的水平。我應該如何處理這個?

在每個 Unix 機器上的任何 shell 中使用任何 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. 使用許多單字元變數名稱,恕我直言,這種大小的腳本對於新手來說更難理解,
  2. 用於NF--刪除 wsg 值,但遞減 NF 是未定義的行為,因此不可移植,並且
  3. 硬編碼標題的行數(這可能沒有錯,只是我傾向於通過分析文本來確定這一點 - 但這也可能是錯誤的,具體取決於實際輸入是否總是看起來像發布的範例,並且,如果不是,它有什麼不同)。

引用自:https://unix.stackexchange.com/questions/634169