使用awk将列中的值替换为txt文件中的另一个值

时间:2016-07-30 19:58:11

标签: linux bash awk

我是linux和awk脚本的新手。我有tab delim txt文件,如下所示:

AAA   134  145  Sat    150   167
AAA   156  167  Sat    150   167
AAA   175  187  Sat    150   167 

我想用最后一行,第五列(150 + 1)中的值替换最后一行,第二列(175)中的值,以便我的最终输出看起来像

AAA   134  145  Sat    150   167
AAA   156  167  Sat    150   167
AAA   151  187  Sat    150   167

我尝试了awk '$2=$5+1' file.txt,但它更改了我不想要的第二列中的所有值。我想用150(+1)替换175。请指导我

2 个答案:

答案 0 :(得分:3)

难点在于,与sed不同,awk并没有告诉我们什么时候我们正在处理最后一行。这是一个解决方法:

$ awk 'NR>1{print last} {last=$0} END{$0=last;$2=$5+1;print}' OFS='\t' file.txt
AAA     134     145     Sat     150     167
AAA     156     167     Sat     150     167
AAA     151     187     Sat     150     167

这可以通过将前一行保留在变量last中来实现。更详细:

  • NR>1{print last}

    对于除第一行以外的每一行,请打印last

  • last=$0

    更新last

  • 的值
  • END{$0=last; $2=$5+1; print}

    当我们到达文件末尾时,更新字段2并打印。

  • OFS='\t'

    将输出上的字段分隔符设置为选项卡。

替代方法

此方法读取文件两次,首先计算行数,第二次读取最后一行。因此,效率较低,但可能更容易理解:

$ awk -v n="$(wc -l <file.txt)" 'NR==n{$2=$5+1} 1' OFS='\t' file.txt
AAA     134     145     Sat     150     167
AAA     156     167     Sat     150     167
AAA     151     187     Sat     150     167

改为改变第一行

$ awk 'NR==1{$2=$5+1} 1' OFS='\t' file.txt
AAA     151     145     Sat     150     167
AAA     156     167     Sat     150     167
AAA     175     187     Sat     150     167

更改第一行和最后一行

$ awk 'NR==1{$2=$5+1} NR>1{print last} {last=$0} END{$0=last;if(NR>1)$2=$5+1;print}' OFS='\t' file.txt
AAA     151     145     Sat     150     167
AAA     156     167     Sat     150     167
AAA     151     187     Sat     150     167

答案 1 :(得分:2)

@ John1024的回答非常有用。

awk内置getline函数来处理文件。

在成功时返回1,在文件末尾返回0,在错误时返回-1

awk '{ 
        line=$0; 
        if (getline == 0 ) {
           $2=$5+1; 
           print $0; 
        } else { 
           print  line RS $0;
        }
     }' OFS='\t' file.txt