1

I have two comma separated files as mentioned below,

cat source.txt
A,1000
B,3000
C,2500
D,5000
E,4000
F,3000

cat test.txt
A,1000
C
D,5000
B
E

How can I update file test.txt by referring file source.txt, such that the expected output is as below,

cat test.txt
A,1000
C,2500
D,5000
B,3000
E,4000

2 Answers2

3

Try:

$ awk -F, -v OFS=, 'FNR==NR{a[$1]=$2; next} NF==1{$2=a[$1]} 1' source.txt test.txt 
A,1000
C,2500
D,5000
B,3000
E,4000

How it works:

  1. -F, -v OFS=,

    This sets the input and output field separator to a comma.

  2. FNR==NR{a[$1]=$2; next}

    When reading the first file, source.txt, save the value of the second field, $2, in associative array a under the key of the first field, $1. Then skip the rest of the commands and jump to start over on the next line.

  3. NF==1{$2=a[$1]}

    If the current line has only one field, assign the second field to the value in associative array a.

  4. 1

    This is short-hand for print the line.

Making permanent changes to the file

With any version of awk, we can make a permanent update to file test.txt with (recommended):

awk -F, -v OFS=, 'FNR==NR{a[$1]=$2; next} NF==1{$2=a[$1]} 1' source.txt test.txt >temp && mv temp test.txt

Alternatively, if one has a recent version of GNU awk (sometimes called gawk):

awk -i inplace -F, -v OFS=, 'FNR==NR{a[$1]=$2; print; next} NF==1{$2=a[$1]} 1' source.txt test.txt
John1024
  • 74,655
  • Thanks John! It worked. However it is not making permanent changes in test.txt file. Please advice how can we make permanent changes in file. – Swapnil Dhule May 15 '19 at 10:02
  • @SwapnilDhule You're welcome. I updated the answer with a method for making permanent changes to the file. – John1024 May 15 '19 at 17:06
-1

I have done by below method and it worked fine

command:

for i in `awk -F "," '{print $1}' file2`; do k=`awk -F "," -v i="$i" '$1 == i {print $2}' file1`; echo $i;echo $k;done| sed "N;s/\n/,/g"

output

A,1000
C,2500
D,5000
B,3000
E,4000
  • Let me know the reason for down vote – Praveen Kumar BS May 15 '19 at 16:06
  • 1
    Perhaps it's because your solution is fragile based on the data -- you're passing fields through the shell. Consider a file2 example with column 1 data of foo* and a file named foobar in the current directory. The shell will expand foo* to foobar and begin matching (or not matching!) data from file1. It also relies on the data never being (mis)interpreted by echo. See https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice and https://unix.stackexchange.com/q/65803/117549 – Jeff Schaller May 16 '19 at 01:39