Text-Processing

在保持文件結構的同時將列 x-end 相乘

  • August 16, 2019

我有一個輸入 File1,它看起來像這樣:

A,22,1,2,3,4,5
G,26,5,6,7
X,28,10,20,10

我想在保持文件結構的同時將方程應用於第 3 列。例如,如果我想要使用的等式乘以 2,我正在尋找輸出:

A,22,2,4,6,8,10
G,26,10,12,14
X,28,20,40,20

我嘗試使用以下命令執行此操作:

awk -F ',' '{for(i=1; i<=NF; i++) if (i >= 3)
    print 2*$i
 else
   print $i }' File1

這提供了正確的輸出,但擺脫了所有文件結構。如果使用我希望使用的實際等式是: 2*(2*($i-1)+1)

非常感謝伴隨解決方案的任何解釋,因為我對此仍然很陌生!

您只需要設置輸出欄位分隔符 ( OFS),例如:

awk '{ for (i=3; i<=NF; i++) $i*=2 } 1' FS=, OFS=, infile

或使用您的公式:

awk '{ for (i=3; i<=NF; i++) $i = 2*(2*($i-1)+1) } 1' FS=, OFS=, infile

輸出:

A,22,2,4,6,8,10
G,26,10,12,14
X,28,20,40,20

1腳本末尾的{ print $0 }

Perl可以如圖所示處理:根據@Thor的建議:

$ perl -F, -anE '$,="," ; say splice(@F,0,2), map { 2*(2*($_-1)+1) } @F' inp.csv

使用另一種方​​法:

$ perl -lpe '
  /^[^,]*,[^,]*/g; #positions the search engine before the 2nd comma.
  s/\G,\K([^,]*)/2*(2*($1-1)+1)/ge;
' inp.csv

GNU 桌面計算器實用程序可以這樣做:

$ < inp.csv tr ',-'  ' _' | sed -Ee 's/\S+/[&]/' |
   dc -e "
    [q]sq
    [44an]s,
    [1-2*1+2*]s=
    [SM lN1+sN z0<a]sa
    [LMnl,x LMnl,x lN2-sN]sb
    [LMl=xn lN1<, lN1-dsN0<c]sc
    [?z0=q 0sN lax lbx lcx 10an z0=?]s?
    l?x
"

這些是根據要求提供的簡單實用程序和解釋,因為它們是簡單直接的程式碼。

簡要說明:

dc實用程序在儲存其數據和程式碼的堆棧上工作。從這裡它將 n 檢索儲存在寄存器中。

字元串數據用方括號括起來。

Lopping是通過遞歸完成的。

在這個 dc 程式碼中有 7 個寄存器儲存程式碼,即 q = , abc ?

兩個寄存器MN儲存數據。

從頭向後工作。程式碼寄存器 ? 執行從輸入讀取下一行的操作。然後比較它的堆棧上有多少空格分隔的項目;將它們視為欄位。在 0 情況下,停止 n 退出。z0=q 片段可以做到這一點。它讀作: z 是 dc 命令,用於返回存在的元素數。我們與 0 比較,如果相等,則執行儲存在寄存器 q 中的程式碼。

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