2013-04-02 22 views
4

我有一堆不同的文件。所有文件都包含標題爲ID的列,但不一定在所有文件的相同位置。我有一個函數,我想在所有文件中應用ID來將它們更改爲NEWID。awk - 僅對一列應用函數,具有可變位置

我知道,如果我通過在ID的列數,我可以做到這一點很簡單,說這是一個5列文件的東西,如第3列:

awk -v column=$COLNUMBER '{print $1, $2, FUNCTION($column), $4, $5}' FILE 

但是,如果我的所有文件有數百個列,它在每個文件中都是任意的,這是令人難以置信的乏味。我正在尋找一種方式來沿着這一行做一些事情:

awk -v column=$COLNUMBER '{print #All columns before $column, FUNCTION($column), #All columns after $column}' FILE 

我已經嘗試了不同的循環,但沒有得到任何對工作還沒有。提示讚賞!

回答

5

簡單:字段之間

$ awk -v column=$COLNUMBER '{ $column = FUNCTION($column); print }' $FILE 
+1

只是意識到它會壓縮字段之間的所有空間到一個空格,並將刪除所有空的字段,因此空字段之外的字段將被左移。 –

+0

哇,這是完美的。 Awk有很多不同的語法選項,我很困惑。要解決間距問題,只需以'{OFS =「\ t」開始,然後它就像一個魅力。 謝謝! – user2233907

+0

請注意,如果字段之間的間距很大,則字段分隔符不是真正的默認空白分隔符。要使此解決方案能夠工作並保留空間,您必須首先爲數據添加一個真實的字段分隔符。也許你知道的逗號或其他角色不會出現在任何有效的字段中。使用單獨的awk腳本很容易。 –

1

保留間距:

$ cat file 
a b c  d e f 
$ gawk -v col=3 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1FUNCTION($col)","")}' file 
a b FUNCTION($col)  d e f 

,或者如果你實際上是在尋找的列值傳遞給函數():

$ gawk -v col=3 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})([^[:space:]]+)","\\1FUNCTION(\\3)","")}' file 
a b FUNCTION(c)  d e f 

$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})([^[:space:]]+)","\\1FUNCTION(\\3)","")}' file 
a b c  FUNCTION(d) e f 

或者:

$ gawk -v col=3 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1FUNCTION($"col")","")}' file 
a b FUNCTION($3)  d e f 

$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1FUNCTION($"col")","")}' file 
a b c  FUNCTION($4) e f 

上面使用GNU awk for gensub(),可以使用多個sub()或match()+ substr()在其他awks中完成相同的操作。

從其他人的回答看來,您可能實際上希望對該字段的值調用FUNCTION(),而不是打印FUNCTION(field)。如果是這種情況,那麼你只需要:

$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1"FUNCTION($col),"")}' file 

例如如果函數是toupper():

$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1"toupper($col),"")}' file 
a b c  D e f