Сравните первый столбец из 2-х файлов на основе второго столбца, используя разделитель;

Мне нужно сравнить ниже 2 файлов.

head_file :

  2345;int builder( 1000;char type::edit::display <test>( 250;void unamed_string_tree* 

ref_file :

  2000;int builder( 500;char type::edit::display <test>( 3000;fillTest*( 

Желаемый результат:

 FUNCTION,HEAD,REF,DIFF int builder(,2345,2000,-345 char type::edit::display <test>(,1000,500,-500 void unamed_string_tree*,250,0,-250 fillTest*(,0,3000,3000 

С 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_file 

Объяснение :

  • -F";" указывает точку с запятой ; как разделитель.
  • Правило BEGIN{...} выполняется только один раз, прежде чем будет прочитана первая входная запись. В этом правиле OFS (разделитель выходных полей) устанавливается в запятую , а строка заголовка печатается: FUNCTION,HEAD,REF,DIFF .
  • FNR==NR применяется для первого обрабатываемого файла: ref_file .
    • a[$2]=$1;next Содержимое файлов теперь хранится в массиве с именем a с индексом $2 и значением $1 .
  • {…} этот блок применяется для каждой строки второго файла: head_file :
    • print ... значения будут напечатаны с соответствующим значением в ранее созданном массиве. Извещение [$2]*1 ; когда значение пусто, умножение с *1 заканчивается нулем 0 .
    • delete a[$2] : по окончании удалить элемент массива.
  • Правило END{...} выполняется только один раз, после чтения последней входной записи.
    • for (i in a) : Loop через остальную часть массива a которая еще не удалена.
    • print ... : Распечатать его индексы и значения.

Выход :

 FUNCTION,HEAD,REF,DIFF int builder(,2345,2000,-345 char type::edit::display <test>(,1000,500,-500 void unamed_string_tree*,250,0,-250 fillTest*(,0,3000,3000