只修改一个大文件的一列,并在unix中保持字段分隔符相同

时间:2013-05-08 09:41:21

标签: unix tabs awk field

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

例如:

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

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

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

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

如何在不丢失制表符分隔版本的情况下执行此操作?

2 个答案:

答案 0 :(得分:2)

您想将FS (字段分隔符)OFS (输出字段分隔符)设置为标签:

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

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

修改

awk的结构是conditional{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语句跳转到下一行在文件 ie:

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

如果在此执行第一个块,则第二个字段取值1201,然后我们抓住下一行,否则第二个字段将取值1202.因此第二个字段将始终采用新值{{1} }或1201

1202 if将是:

elif

这里第二个字段可能采用一个新值,如果确实如此,即使条件为真,第三个字段也不会更新,因为它永远不会被评估。如果第一个条件为FALSE且第二个条件为TRUE,则只能更新第三个字段。

答案 1 :(得分:0)

 sed -r 's/^ *[^ ]+ +120\b/\01/' file