combine multiple string replacement awk commands into one

Viewed 75

I have two separate awk commands that replaces the third column of specific rows of the destination_file with the third column of specific rows of the source file. The commands work but is cumbersome with a lot of IO operations. Is there a way to combine the awk commands into one?

The commands I have at the moment are:

z2=$(awk 'NR==12 { print$1 }' ../source_folder/source_file)
z3=$(awk 'NR==14 { print$1 }' ../source_folder/source_file)


awk -v z2=$z2 'NR==10{$3=z2} 1' destination_file > temp && mv temp destination_file
awk -v z3=$z3 'NR==11{$3=z3} 1' destination_file > temp && mv temp destination_file

As an expansion to this problem, the rows I obtain values for z2, z3, z4 ... are from NR==12, 14, 16 ... and the rows in the destination_file that I want to replace are NR==10, 11, 12 ...; is there a way to write a sequence to do this string replacement operation instead of listing all the z1, z2, z3 ...?

2 Answers

You could combine both of your programs into one. Have only 1 awk program to check both conditions NR==10 and NR==11 and do respective assignments of values to respective fields as per condition. This will save output into output file then.

z2=$(awk 'NR==12 { print$1 }' ../source_folder/source_file)
z3=$(awk 'NR==14 { print$1 }' ../source_folder/source_file)

awk -v z2="$z2"  -v z3="$z3" 'NR==10{$3=z2} NR==11{$3=z3} 1' destination_file > temp && mv temp destination_file

You don't need multiple calls to awk and shell variables for this:

awk '
    NR==FNR {
        if      ( FNR==12 ) { map[10] = $1 }
        else if ( FNR==14 ) { map[11] = $1; nextfile }
        next
    }
    FNR in map {
        $3 = map[FNR]
    }
    { print }
' ../source_folder/source_file destination_file

or if your line numbers always increase by 2 in the source file and 1 in the dest file:

awk '
    NR==FNR {
        if ( (12 <= FNR) && !(FNR%2) ) {
            map[10 + (c++)] = $1
        }
        next
    }
    FNR in map {
        $3 = map[FNR]
    }
    { print }
' ../source_folder/source_file destination_file
Related