Awk

awk 將所有行按列除以另一行

  • April 25, 2020

我正在嘗試將 file1.txt 中的所有行除以 file2.txt 中單行中它們各自的(按列)值。

貓文件1.txt

1       2.5     3
7       7       7
1       3       5

貓文件2.txt

1   3   5

按照這個問題的建議解決方案:https ://stackoverflow.com/questions/44908195/awk-multiplication-of-all-rows-in-a-table-with-first-row-of-the-table ,我來了使用以下程式碼:

cat file2.txt file1.txt | awk 'NR==1{split($0,m);CONVFMT="%.5f\t";next} {for (i=1;i<=NF;i++) $i=$i/m[i]} 1'

但是,由於其中一行中的所有值都等於 1,並且 CONVFMT 不適用於整數,因此我的輸出文件中的格式被弄亂了。為了解決這個問題,我正在考慮使用帶有製表符分隔符而不是 CONVFMT 的 printf,但鑑於我的實際文件具有可變數量的列,我不想要使用硬編碼的解決方案 $ 1, $ 2 等等。我不精通 awk,所以我不能自己想出一個修復方法。

非常感謝您的幫助!

編輯:輸出中的所有數字都應格式化為 %.5f。

如果您希望所有欄位格式為%.5f,您可以使用sprintf

BEGIN {
   OFS = "\t"
}

NR == 1 {
   cols = split($0,m)
   next
}

NF == cols {
   for (i=1; i<=NF; i++)
       $i = sprintf("%.5f", $i/m[i])
}

1

$ awk -f above.awk file2 file1
1.00000 0.83333 0.60000
7.00000 2.33333 1.40000
1.00000 1.00000 1.00000

上面的awk程序沒有警告可能的錯誤。你可以試試:

NR == 1 {
   cols = split($0,m)
   for (i in m)
       if (m[i] == 0)
           err("field "i" is "m[i]"; division by zero is fatal", 1)
   next
}

NF != cols {
   err("found "NF" fields, expected "cols)
   next
}

{
   for (i in m)
       $i = sprintf("%.5f", $i/m[i])
   print
}


END {
   exit errs
}

function err(msg, r) {

   # Print message to stderr
   # Leave non-zero exit status
   # Optionally go to END

   printf "%s - %s.\n", "error:  line "FNR" in "FILENAME, msg | "cat >&2"
   errs = 1
   if (r) exit
}

此外,您可能需要檢查每個欄位是否為數字:Make awk generate error on non-numeric我可以確定 awk 變數的類型嗎?

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