Skip to main content
add explanation
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118

OutputHere, we pass line numbers as an awk -variable in a='...' (for fileA) and b='...' (for fileB), then we split() them into an array on comma character as the separator (note that a and b were variables, while now ax and bx are arrays).

then we build a another mapping array from ax and bx arrays to map the lines which those should be replaced in fileA with the ones from fileB;

now keys (or indexes) of the mapping array is line numbers of the fileB and the values of these keys are the line numbers of the fileA, as below:

the mapping array is:

ItalyKey    Value
Argentina1      2
USA2      4
5      5
8      7

so now what we need, that is, just to read the line numbers from fileB that match with the keys above (FNRs of 1, 2, 5 and 8), so we do that with:

NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };

OK, now what is the value of the mapping[FNR]? if you check the mapping array above, that would be:

mapping[1] --> 2; then-we-have    hold[ mapping[1] ] --> hold[2]=$0
mapping[2] --> 4; then-we-have    hold[ mapping[2] ] --> hold[4]=$0
mapping[5] --> 5; then-we-have    hold[ mapping[5] ] --> hold[5]=$0
mapping[8] --> 7; then-we-have    hold[ mapping[8] ] --> hold[7]=$0

so we used the value of mapping array as the key for the hold array and hold array is now contains:

Key     Value
2       Argentina
4       Switzerland
5       Denmark
Japan
7       Colombia

now the last step is to use keys in hold array as the matched line number in fileA and replace that lines with the values of that key from the hold array if that line number found in the array or print the line itself if not found (Ternary operator: condition? if-true : if-false), and we do that with:

{ print (FNR in hold)? hold[FNR]: $0; }

Output is:

Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia

Here, we pass line numbers as an awk -variable in a='...' (for fileA) and b='...' (for fileB), then we split() them into an array on comma character as the separator (note that a and b were variables, while now ax and bx are arrays).

then we build a another mapping array from ax and bx arrays to map the lines which those should be replaced in fileA with the ones from fileB;

now keys (or indexes) of the mapping array is line numbers of the fileB and the values of these keys are the line numbers of the fileA, as below:

the mapping array is:

Key    Value
1      2
2      4
5      5
8      7

so now what we need, that is, just to read the line numbers from fileB that match with the keys above (FNRs of 1, 2, 5 and 8), so we do that with:

NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };

OK, now what is the value of the mapping[FNR]? if you check the mapping array above, that would be:

mapping[1] --> 2; then-we-have    hold[ mapping[1] ] --> hold[2]=$0
mapping[2] --> 4; then-we-have    hold[ mapping[2] ] --> hold[4]=$0
mapping[5] --> 5; then-we-have    hold[ mapping[5] ] --> hold[5]=$0
mapping[8] --> 7; then-we-have    hold[ mapping[8] ] --> hold[7]=$0

so we used the value of mapping array as the key for the hold array and hold array is now contains:

Key     Value
2       Argentina
4       Switzerland
5       Denmark
7       Colombia

now the last step is to use keys in hold array as the matched line number in fileA and replace that lines with the values of that key from the hold array if that line number found in the array or print the line itself if not found (Ternary operator: condition? if-true : if-false), and we do that with:

{ print (FNR in hold)? hold[FNR]: $0; }
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118

Using awk:

awk -v a='2,4,5,7' -v b='1,2,5,8' '
BEGIN { split(a, ax, ","); split(b, bx, ",");
        for(n in ax) mapping[ bx[n] ] =ax[n];
};
NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };
{ print (FNR in hold)? hold[FNR]: $0; }' fileB fileA

Output is:

Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia