Skip to content
Advertisement

Using awk to make changes to nth character in nth line in a file

I have written an awk command

awk 'NR==5 {sub(substr($1,14,1),(substr($1,14,1) + 1)); print "test.py"}' > test.py

This is trying to change the 14th character on the 5th line of a python file. For some reason this doesn’t stop executing and I have to break it. It also deletes the contents of the file.

Sample input:

import tools

tools.setup(
    name='test',
    tagvisc='0.0.8',
    packages=tools.ges(),
    line xyz
)

`

Output:

import tools

tools.setup(
    name='test',
    tagvisc='0.0.9',
    packages=tools.ges(),
    line xyz
)

Advertisement

Answer

Get away from the fixed line number (NR==5) and fixed character position (14) and instead look at dynamically finding what you want to change/increment, eg:

$ cat test.py
import tools

tools.setup(
    name='test',
    tagvisc='0.0.10',
    packages=tools.ges(),
    line xyz
)

One awk idea to increment the 10 (3rd line, 3rd numeric string in line):

awk '
/tagvisc=/ { split($0,arr,".")                             # split line on periods
             sub("." arr[3]+0 "47","." arr[3]+1 "47")  # replace .<oldvalue>47 with .<newvalue>47; 47 == single quote
           }
1
' test.py

NOTES:

  • arr[3] = 10',; with arr[3]+0 awk will take the leftmost all-numeric content, strip off everything else, then add 0, leaving us with arr[3] = 10; same logic applies for arr[3]+1 (arr[3]+1 = 11); basically a trick for discarding any suffix that is not numeric
  • if there are multiple lines in the file with the string tagvisc='x.y.z' then this will change z in all of the lines; we can get around this by adding some more logic to only change the first occurrence, but I’ll leave that out for now assuming it’s not an issue

This generates:

import tools

tools.setup(
    name='test',
    tagvisc='0.0.11',
    packages=tools.ges(),
    line xyz
)

If the objective is to overwrite the original file with the new values you have a couple options:

# use temporary file:

awk '...' test.py > tmp ; mv tmp test.py

# if using GNU awk, and once accuracy of script has been verified:

awk -i inplace '...' test.py
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement