Awk 仅对一列应用函数,并使用可变位置

Awk 仅对一列应用函数,并使用可变位置,awk,Awk,我有一大堆不同的文件。所有文件都包含标题为ID的列,但不一定在所有文件中的同一位置。我有一个函数,我想应用于所有文件中的ID,将它们更改为NEWID 我知道,如果我传入ID的列号,我可以做得非常简单,比如说它是5列文件中的第3列,类似于: awk -v column=$COLNUMBER '{print $1, $2, FUNCTION($column), $4, $5}' FILE 但是,如果我的所有文件都有数百列,并且每个文件中都有任意的列,那么这就非常乏味了。我正在寻找一种方法,按照以下

我有一大堆不同的文件。所有文件都包含标题为ID的列,但不一定在所有文件中的同一位置。我有一个函数,我想应用于所有文件中的ID,将它们更改为NEWID

我知道,如果我传入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
我已经尝试了不同的循环,但还没有任何一个循环可以工作。

简单:

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

保留字段之间的间距:

$ 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
或者,如果您实际上正在查找要传递给函数()的列值:

或:

上面使用GNU awk for gensub(),您可以在其他awk中使用多个子()或match()+substr()实现相同的功能

从其他人的回答来看,您可能实际上希望对字段的值调用FUNCTION(),而不是打印函数(field)。如果是这样,那么您只需执行以下操作:

$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1"FUNCTION($col),"")}' file
e、 g.如果函数是toupper():


请注意,它会将字段之间的所有空格压缩为单个空格,并删除所有空字段,因此空字段以外的字段将左移。哇,这太完美了。Awk有这么多不同的语法选择,哈哈,我都搞糊涂了。要解决间距问题,只需从“{OFS=“\t”开始然后它就像一个符咒。非常感谢!请注意,如果字段之间的间距很大,那么您的字段分隔符实际上并不是默认的空白分隔符。要使此解决方案起作用并保留空格,您必须首先向数据中添加一个实实在在的字段分隔符。可能不会出现逗号或其他您知道的字符在任何有效字段中。使用单独的awk脚本很容易做到这一点。
$ 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
$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1"FUNCTION($col),"")}' file
$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1"toupper($col),"")}' file
a b   c      D e  f