Text-Processing

非固定列數的逐行算術計算

  • August 30, 2017

我有一個帶有非固定列號的輸入文件,我想對其進行一些算術計算:

input.txt
ID1    4651455    234     4651765    392     4652423      470
ID2    16181020   176    16184958    869     16185889     347    16187777     231

ID輸入文件具有製表符分隔的欄位在列中始終具有唯一性$1(不重複)。並非所有行都具有相同的列數。

我想要實現的是一個製表符分隔的文件,如下所示:

output1.txt
ID1     76    266   
ID2     3762   62   1541  

基本上它會列印$1原始文件的,然後它會從文件的第二個偶數列($4)開始,減去前兩列($4– )的值$3$2然後對輸入文件的所有偶數列執行相同的操作(例如$6- $5- $4; $8- $7- $6; …)。據我所知,這可以用 來完成awk print,但我只知道當我的文件在每一行中都有固定數量的列時如何處理它。

滿足我的需求的更理想的輸出如下:

output2.txt
ID1    234    76    392    266   470
ID2    176   3762   869    62    347   1541  231

基本上它會列印$1原始文件的,然後將輸入文件中的奇數列交錯列印到列中,如output1.txt.

$ awk -v OFS='\t' -f script.awk file
ID1     76      266
ID2     3762    62      1541

script.awk在哪裡

{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }

將為文件中的每一行輸入執行所有塊。

第一個塊輸出 ID。

第二個塊按照您的描述遍歷欄位並輸出由OFS(輸出欄位分隔符,設置為命令行上的選項卡)分隔的數據。

最後一個塊簡單地輸出記錄分隔RS符,預設情況下是換行符。

或者,

BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }

擺脫對-v OFS='\t'.

作為“單線”:

$ awk 'BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }' file

對於擴展問題:

{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d%s%d", OFS, $(i-1), OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s%d%s%s", OFS, $NF, OFS, RS) }

這將直接從原始文件生成以下內容:

ID1     234     76      392     266     470
ID2     176     3762    869     62      347     1541    231

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