Awk

如何從第 1 列和第 2 列中提取最大值和最小值

  • November 16, 2020

親愛的,我有一個數據文件,可以說file.dat,它包含兩列

例如 file.dat(顯示幾行)

   0.0000  -23.4334
   0.0289  -23.4760
   0.0578  -23.5187
   0.0867  -23.5616
   0.1157  -23.6045
   0.1446  -23.6473
   0.1735  -23.6900
   0.2024  -23.7324
   0.2313  -23.7745
   0.2602  -23.8162
   0.2892  -23.8574
   0.3181  -23.8980
   0.3470  -23.9379
   0.3759  -23.9772
   0.4048  -24.0156
   0.4337  -24.0532
   0.4627  -24.0898
   0.4916  -24.1254
note: data file has a blank line at the end of the file

預期成績

我想從兩個列中查找/提取最大值和最小值,例如 column-1

max - 0.4916
min - 0.0000

同樣第 2 列

max - -23.4334
min - -24.1254

不完整的解決方案(不適用於第 2 列)

對於第 1 列

awk 'BEGIN{min=9}{for(i=1;i<=1;i++){min=(min<$i)?min:$i}print min;exit}' file.dat 
0.0000
cat file.dat | awk '{if ($1 > max) max=$1}END{print max}'
0.4916

對於第 2 列

awk 'BEGIN{min=9}{for(i=2;i<=2;i++){min=(min<$i)?min:$i}print min;exit}' file.dat
-23.4334

cat file.dat | awk '{if ($2 > max) max=$2}END{print max}'
**no output showing**

問題

請幫我從第 2 列中找到最小值和最大值 注意:數據文件在文件末尾有一個空行

您的程式碼中的問題,

awk 'BEGIN{min=9}{for(i=2;i<=2;i++){min=(min<$i)?min:$i}print min;exit}' file.dat

…是您exit在處理第一行輸入後立即。你的中間塊需要為每一行觸發。然後,在一個END塊中,您可以列印您找到的值。您可以在另一個程式碼片段中執行此操作:

awk '{if ($1 > max) max=$1}END{print max}'

另一個問題是您min使用幻數進行初始化(我引用的第一個程式碼中為 9,第二個程式碼中為 0;如果您在計算中使用未顯式初始化的變數,則其值為 0)。如果這個幻數不在實際數據中的數字範圍內,那麼計算的最小值和/或最大值將是錯誤的。最好將最小值和最大值都初始化為數據中的某個值。

要跟踪最小值和最大值,您需要兩個變數,並且需要根據文件中每一行的數據檢查這兩個變數,以查看它們是否需要更新*。*

由於awk支持數組,因此很自然地將數組用於minand max,每列一個數組元素。這就是我在下面的程式碼中所做的。


推廣到任意數量的列:

NF == 0 {
       # Skip any line that does not have data
       next
}

!initialized {
       # Initialize the max and min for each column from the
       # data on the first line of input that has data.
       # Then immediately skip to next line.

       nf = NF

       for (i = 1; i <= nf; ++i)
               max[i] = min[i] = $i

       initialized = 1
       next
}

{
       # Loop over the columns to see if the max and/or min
       # values need updating.

       for (i = 1; i <= nf; ++i) {
               if (max[i] < $i) max[i] = $i
               if (min[i] > $i) min[i] = $i
       }
}

END {
       # Output max and min values for each column.

       for (i = 1; i <= nf; ++i)
               printf("Column %d: min=%s, max=%s\n", i, min[i], max[i])
}

鑑於此腳本和問題中的數據:

$ awk -f script.awk file
Column 1: min=0.0000, max=0.4916
Column 2: min=-24.1254, max=-23.4334

NF == 0一個塊(對所有行執行)的條件是確保我們跳過空白行。測試的意思是“如果這條線上有零個數據欄位(列)”。該變數initialized將從一開始就為零(邏輯上為false ),但在讀取第一行有數據時將設置為一(邏輯上為true )。

在我們初始化和值的那一行,nf變數被初始化為NF(欄位數) 。這樣即使最後一行的欄位為零,塊中的輸出也能正常工作。min``max``END

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