Carol Carol - 4 months ago 14
Bash Question

Replacing value in column with another value in txt file using awk

I am new to linux and awk scripting. I have tab delim txt file like follows:

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

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. I want replace only 175 with 150(+1). Kindly guide me

Answer

The difficulty is that, unlike sed, awk does not tell us when we are working on the last row. Here is one work-around:

$ awk 'NR>1{print last} {last=$0} END{$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. In more detail:

  • NR>1{print last}

    For every row, except the first, print last.

  • last=$0

    Update the value of last.

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

    When we have reached the end of the file, update field 2 and print.

  • 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{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
Comments