4

我有一堆不同的文件。所有文件都包含一个标题为 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

我尝试了不同的循环,但还没有任何工作。

4

2 回答 2

5

简单的:

$ awk -v column=$COLNUMBER '{ $column = FUNCTION($column); print }' $FILE
于 2013-04-02T17:47:37.720 回答
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

或者如果您实际上正在寻找要传递给 FUNCTION() 的列值:

$ 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 进行 gensub(),您可以在其他 awk 中使用多个 sub() 或 match()+substr() 完成相同的操作。

从其他人的答案看来,您实际上可能想在字段的值上调用 FUNCTION(),而不是打印 FUNCTION(field)。如果是这种情况,那么您只需执行以下操作:

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

例如,如果 FUNCTION 是 toupper():

$ gawk -v col=4 '{print gensub("([[:space:]]*([^[:space:]]+[[:space:]]+){" col-1 "})[^[:space:]]+","\\1"toupper($col),"")}' file
a b   c      D e  f
于 2013-04-02T17:59:59.777 回答