Как найти все строки из file1, которых нет в file2

По работе возникла такая задача. 

Имеется csv-файл со списком автомобилей более 170 строк. Пусть будет «file1.csv». 

Имеется другой аналогичный файл со списком автомобилей. Пусть будет «file2.csv»

Требуется найти все строки из файла «file1.csv», которых нет в файле «file2.csv»

Задача довольно простая, но если это делать вручную, то будет очень долго. Особенно, если учесть, что в каждом файле своя сортировка. Это задачу можно решить различными манипуляциями с помощью Excel, но это довольно муторно.

Но оказывается эта задача решается гораздо проще с помощью команды терминала «comm».

# comm [options] file1 file2

comm — построчно сравнивает сортированные файлы file1 и file2. Без опций команда выдает три столбца. В первом столбце будут строки, которые встречаются только в file1. Во втором столбце будут строки, которые встречаются только в file2. А в третьем столбце будут строки, которые встречаются только в обоих файлах. Очень удобно!

С помощью опций можно исключить из вывода не нужные столбцы.

[options]
-1 - исключает первый столбец
-2 - исключает второй столбец
-3 - исключает третий столбец

В нашем случае, нам нужен только первый столбец. Команда будет выглядеть так:

comm -23 file1.csv file2.csv

Но на самом деле эта команда не будет правильно работать, ведь файлы не отсортированы. Чтобы команда сработала как надо файлы надо сначала отсортировать.

Вот эта команда решает поставленную задачу

comm -23 <(sort 001.csv) <(sort 002.csv) --total

Вывод команды будет такой:

Легковой;Киа Рио;Р963УС 777;Р15-23171-ДЛ;335860;24.05.2018
Легковой;Мерседес Бенц GLK300;Б/Н;Р14-21985-ДЛ;351655;27.06.2018
Легковой;фольцваген поло;МК129 77;Р17-13389-ДЛ;155654;21.12.2017
3 49 122 итого

Что и требовалось!

Но эту команду можно ещё больше усовершенствовать. То что здесь требуется — эту узнать какие автомобили из file1 не попали в file2. Но в строчке может быть не значащая для этих целей информация, например, порядковый номер или текущая дата. Эту информацию можно исключить из обработки с помощью команды awk.

В этом случае, команда будет выглядеть следующим образом:

comm -23 <(awk -F";" '{print $3,$4,$5}' 001.csv|sort) <(awk -F";" '{print $3,$4,$5}' 002.csv|sort) --total