Awk

當正斜杠(/)在輸入中時,gawk 中的算術(除法) - 可能有多個欄位分隔符?

  • October 26, 2022

我有一個文件,其行類似於以下內容(不幸的是,這是另一個軟體輸出結果的唯一格式):

1 2 3 5/2 7 17/5 9 10/3 15

我需要用以下行替換它:

1 2 3 2.5 7 3.4 9 3.33 15

換句話說,我希望 GAWK 進行除法並 5/2, 17/5 and 10/3 用它們的十進制值 替換分數(有理數)2.5, 3.4 and 3.33.

我嘗試了多個 FS(欄位分隔符),但沒有任何效果。使用 GAWK 有什麼好方法?謝謝。

如果我將其更改slash (/)為 a會更容易colon (:)嗎?

我為什麼要問這個問題?我試圖搜尋是否/$i.. 的子字元串(如果答案是肯定的,那麼我會將split()$i 分成兩部分,然後進行除法)。

我在其他地方讀到檢查一個欄位是否以$i開頭F,他們使用if ($i~/^F/)- 所以我嘗試了if ($i~///),然後if ($i~/"/"/),然後if ($i~/\//) (escaping / with a \)等等。這些都不起作用..所以我認為/是 Awk 中的一個特殊字元..為了避免特殊字元並發症,我想,讓我用:

遍歷欄位並將每個欄位拆分為/. 如果拆分正好生成兩個子字元串,則使用這些子字元串來計算欄位的新值:

$ awk '{ for (i=1; i<=NF; ++i) if (split($i,a,"/")==2) $i = a[1]/a[2] };1' file
1 2 3 2.5 7 3.4 9 3.33333 15

兩位小數,使用%.2f格式說明符sprintf()

$ awk '{ for (i=1; i<=NF; ++i) { if (split($i,a,"/")==2) $i = sprintf("%.2f",a[1]/a[2]) } };1' file
1 2 3 2.50 7 3.40 9 3.33 15

同樣,使用米勒

$ mlr --nidx put 'for (k,v in $*) { a=splitnv(v,"/"); if (length(a)==2) { $[k]=a[1]/a[2] } }' file
1  2  3  2.500000  7  3.400000  9  3.333333  15
$ mlr --nidx put 'for (k,v in $*) { a=splitnv(v,"/"); if (length(a)==2) { $[k]=fmtnum(a[1]/a[2],"%.2f") } }' file
1  2  3  2.50  7  3.40  9  3.33  15

請注意,使用nidx輸入和輸出格式時,預設欄位分隔符是單個空格字元。這意味著問題中顯示的輸入有 17 個欄位,其中一些是空的。這些都在輸出中複製,這意味著空間被保留。

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