简体   繁体   English

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

[英]Replacing value in column with another value in txt file using awk

I am new to linux and awk scripting. 我是linux和awk脚本的新手。 I have tab delim txt file like follows: 我有标签delim txt文件,如下所示:

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

I would like replace only the value in last row, second column(175) with the value in the last row,5th column(150+1) so that my final output should look like 我只想将最后一行第二列(175)中的值替换为最后一行第五列(150 + 1)中的值,以便最终输出看起来像

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

I tried awk '$2=$5+1' file.txt but it changes all the values in second column which I don't want. 我尝试了awk '$2=$5+1' file.txt但是它更改了我不想的第二列中的所有值。 I want replace only 175 with 150(+1). 我只想用150(+1)代替175。 Kindly guide me 请指导我

The difficulty is that, unlike sed, awk does not tell us when we are working on the last row. 困难在于,与sed不同,awk不会告诉我们何时进行最后一行操作。 Here is one work-around: 这是一种解决方法:

$ 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

This works by keeping the previous line in the variable last . 这通过将变量的前一行保留在last中而起作用。 In more detail: 更详细地:

  • NR>1{print last}

    For every row, except the first, print last . 对于除第一行外的每一行, last打印。

  • last=$0

    Update the value of last . 更新last的值。

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

    When we have reached the end of the file, update field 2 and print. 当我们到达文件末尾时,更新字段2并打印。

  • OFS='\\t'

    Set the field separator on output to a tab. 将输出的字段分隔符设置为选项卡。

Alternate method 替代方法

This approach reads the file twice, first to count the number of lines and the second time to change the last row. 此方法读取文件两次,第一次计数行数,第二次更改最后一行。 Consequently, this is less efficient but it might be easier to understand: 因此,这效率较低,但可能更易于理解:

$ 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

Changing the first row instead 改为更改第一行

$ 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

Changing the first row and the last row 更改第一行和最后一行

$ 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

@John1024 's answer is very informative. @ John1024的答案非常有用。

awk have builtin getline function to process file. awk具有内置的getline函数来处理文件。

It returns 1 on sucess, 0 on end of file and -1 on an error. 成功返回1 ,文件结束返回0 ,错误返回-1

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM