1

我有一个非常大的文件(超过 10000 列)。我想更改第二列中的 3 个条目并保持其他任何内容相同,包括字段分隔符。

例如:

ab123\t123\t0.1
ab234\t120\t0.5

我想检查第二列是否有条目 120 并将其更改为 1201 并保持其他所有内容相同。

我试过awk。它工作正常,但替换用空格分隔的制表符。

awk '{ if ( $2 == 120 ) { $2 = 1201 }; print}' file

我怎样才能做到这一点而不会丢失制表符分隔的版本?

4

2 回答 2

2

您想将FS (字段分隔符)OFS (输出字段分隔符)设置为选项卡:

awk '$2==120{$2=1201}1' FS='\t' OFS='\t' file

OFS是这里的重要变量,因为awk它使用它的值来分隔输出中的字段。

编辑:

的结构awkconditional{block},如果条件评估为 TRUE,则执行该块。因此,$2==120{$2=1201}条件是$2==120如果第二个字段的值是 120,并且块被{$2=1201}分配给第二个字段的值 1201。默认块awk{print $0}这样的:

awk '$2==120{$2=1201}{print $0}'

可以重写为:

awk '$2==120{$2=1201}1'

其中 1 是始终评估为 TRUE 的条件,因为我们没有指定块,{print $0}所以执行默认值。

对于多个条件,只需添加更多结构,即:

awk '$2==120{$2=1201}$3==130{$3==1301}1'

这更像是一种if if结构,因为两个块都可以执行,并且if else会使用该next语句跳转到文件中的下一行,即:

 awk '$2==120{$2=1201;next}{$2==1202}1'

如果在这里执行第一个块,则第二个字段取值 1201,我们抓取下一行,否则第二个字段将取值 1202。所以第二个字段将始终取一个新值,要么1201要么1202

一个if elif将是:

awk '$2==120{$2=1201;next}$3==130{$3==1301}1'

这里第二个字段可能会取一个新值,如果是这样,即使条件为真,第三个字段也不会更新,因为它永远不会被评估。仅当第一个条件为 FALSE 且第二个条件为 TRUE 时,才能更新第三个字段。

于 2013-05-08T09:50:44.467 回答
0
 sed -r 's/^ *[^ ]+ +120\b/\01/' file
于 2013-05-08T09:55:57.263 回答