I have a text file filename
for which I want to substitute a certain numerical string in row row_num
by another one that starts with leading zeros. That row is:
"uuid": "34ba55d4-42fd-448e-862a-f1515"
And I would like to substitute the last four digits so that the desired end result is:
"uuid": "34ba55d4-42fd-448e-862a-f0155"
The command I am using is:
gawk 'NR=='$row_num'{gsub(/'1515'/,'0155')};1' filename > tmp && mv tmp filename
The problem is that linux interprets 0155 as an octal number due to the leading zero and returns:
"uuid": "34ba55d4-42fd-448e-862a-f109"
Resolving the interpretation by adding 10#
to 0155
does not resolve my issue because then it is evaluated and the zero is avoided, yielding:
"uuid": "34ba55d4-42fd-448e-862a-f155"
How can I make the substitution so that I obtain the desired output?
I would like the solution to be general so that it also works in the case where the first element is nonzero, for which my provided solution does work.
Advertisement
Answer
As general practice, following the advice from the commenters, consider moving ALL external input to variables, making the script a ‘constant’. It will eliminate quoting problems, and potential risk from injections of input with special characters.
awk -v row_num="$row_num" -v val="$val" -v "val2=$val2" 'NR==row_num {sub(val,val2)};1' filename # OR awk 'NR==row_num {sub(val,val2)};1' row_num="$row_num" val="$val" "val2=$val2" filename
For larger script, this will make it possible to place the script into ‘file.awk’, simplifying the quoting even further.
replace-one.awk
#! /bin/env awk NR==row_num { sub(val,val2) } {print }
And invoke it with
replace-in-line.sh row_num="$row_num" val="$val" "val2=$val2" filename