Сравнение файлов Awk

два файла, в которых имя компонента и номер версии разделены пробелом:

cat file1
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.1.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.9
com.acc.invm:SendEmail 29.6.113
com.acc.invm:SendSms 12.23.65
com.acc.invm:newSer 10.10.10

cat file2 
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.0.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.10
com.acc.invm:SendEmail 29.60.113
com.acc.invm:SendSms 133.28.65
com.acc.invm:distri_cob 110.10.10

необходимый вывод:

(1) список компонентов из файла1, которые есть в файле1 и отсутствуют в файле2.
(2) список компонентов из файла2, которые есть в файле1 и отсутствуют в файле2.

В этом примере желаемый результат:

компоненты из файла1:

com.acc.invm:newSer 10.10.10

компоненты из файла2:

com.acc.invm:distri_cob 110.10.10

ПРИМЕЧАНИЕ. Мы должны игнорировать, если компоненты представлены с другой версией.

Мой код: (1)

 cat new.awk
 { split($2,a,/\./); curr = a[1]*10000 + a[2]*100 + a[3] }
 NR==FNR { prev[$1] = curr; next }
 !($1 in prev) && (curr > prev[$1])

 /usr/bin/nawk -f new.awk f2 f1

ВЫХОД

com.acc.invm:newSer 10.10.10

(2)

/usr/bin/nawk -f new.awk f1 f2

ВЫХОД

com.acc.invm:distri_cob 110.10.10

Верна ли эта логика? И

кто-нибудь может помочь мне, как я могу написать new.awk в самом моем скрипте, поэтому для его запуска не требуется файл new.awk.


person rKSH    schedule 19.10.2015    source источник


Ответы (3)


Вы можете распечатать уникальные компоненты из обоих файлов одним вызовом awk:

# Save all the components from the first file into an array
NR == FNR { a[$1] = $0; next }

# If a component from the second file is found, delete it from the array
$1 in a { delete a[$1]; next }

# If a component in the second file is not found, print it
{ print }

# Print all the components from the first file that weren't in the second
END { for (i in a) print a[i] }


$ cat file1
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.1.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.9
com.acc.invm:SendEmail 29.6.113
com.acc.invm:SendSms 12.23.65
com.acc.invm:newSer 10.10.10


$ cat file2
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.0.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.10
com.acc.invm:SendEmail 29.60.113
com.acc.invm:SendSms 133.28.65
com.acc.invm:distri_cob 110.10.10


$ awk -f cf.awk file2 file1
com.acc.invm:newSer 10.10.10
com.acc.invm:distri_cob 110.10.10

Что касается второй части вашего вопроса, если вы хотите запустить это, не имея кода в отдельном файле awk, вы можете просто встроить код следующим образом:

 awk 'NR==FNR {a[$1]=$0; next} $1 in a {delete a[$1]; next}1 END {for (i in a) print a[i]}' file2 file1

(Обратите внимание, что 1 перед END равносильно { print }, поскольку 1 всегда верно, а print — действие по умолчанию.)

person jas    schedule 19.10.2015

Могу ли я предложить простой однострочный код, делающий то же самое, но без программирования на awk?

cat file2 file1 file2|cut -f 1 -d" "|sort|uniq -u| xargs -I'{}' grep '{}' file1
com.acc.invm:newSer 10.10.10


cat file1 file2 file1|cut -f 1 -d" "|sort|uniq -u| xargs -I'{}' grep '{}' file2
com.acc.invm:distri_cob 110.10.10
person LiMar    schedule 19.10.2015

Если вам просто нужны имена компонентов (без версий)

$ p() { cut -d' ' -f1 $1 | sort; }; comm -23 <(p file1) <(p file2)
com.acc.invm:newSer

$ p() { cut -d' ' -f1 $1 | sort; }; comm -13 <(p file1) <(p file2)
com.acc.invm:distri_cob

если вам нужны номера версий, вы можете подключиться к

 ... | xargs -I{} grep {} file2

аналогично для файла1, как в решении @LiMar

person karakfa    schedule 19.10.2015