I need to compare below 2 files.The head_file:    2345;int builder(    1000;char type::edit::display <test>(    250;void unamed_string_tree*The ref_file:    2000;int builder(    500;char type::edit::display <test>(    3000;fillTest*(Desired output:FUNCTION,HEAD,REF,DIFFint builder(,2345,2000,-345char type::edit::display <test>(,1000,500,-500void unamed_string_tree*,250,0,-250fillTest*(,0,3000,3000
Compare first column of 2 files based on the second column using the delimiter ;
text processing;files;awk;scripting;merge
With awk:awk -F; 'BEGIN{OFS=,;  print FUNCTION,HEAD,REF,DIFF}  FNR==NR{a[$2]=$1;next}  {print $2,$1,a[$2]*1,a[$2]-$1; delete a[$2]}  END{for (i in a){print i,0,a[i],a[i]}}' ref_file head_fileThe explanation:-F; specifies the semicolon ; as delimiter.The BEGIN{...} rule is executed once only, before the first input record is read. In that rule, the OFS (output field separator) is set to comma , and the header line is printed: FUNCTION,HEAD,REF,DIFF.FNR==NR applies for the first file being processed: the ref_file.a[$2]=$1;next The files contents are now stored in an array called a with the index $2 and the value $1.{...} that block applies for every line of the second file, the head_file:print ... the values are printed with the corresponding value in the previously created array. Notice [$2]*1; when the value is empty the multiplication with *1 ends in a zero 0.delete a[$2]: When finished delete the array element.The END{...} rule is executed once only, after the last input record is read.for (i in a): Loop trough the rest of the array a which is not yet deleted.print ...: Print its indexes and values.The output:FUNCTION,HEAD,REF,DIFFint builder(,2345,2000,-345char type::edit::display <test>(,1000,500,-500void unamed_string_tree*,250,0,-250fillTest*(,0,3000,3000