Есть ли инструмент для получения строк в одном файле, которые не находятся в другом?

Есть ли какой-нибудь инструмент, который может получить строки, которые содержит файл A, но файл B не работает? Я мог бы сделать небольшой простой скрипт, например, perl, но если что-то подобное уже существует, я сэкономлю свое время с этого момента.

Да. Стандартный инструмент grep для поиска файлов для текстовых строк может использоваться для вычитания всех строк в одном файле из другого.

 grep -F -x -v -f fileB fileA 

Это работает, используя каждую строку в файлеB как шаблон ( -f fileB ) и рассматривая его как обычную строку для соответствия (не регулярное регулярное выражение) ( -F ). Вы принудительно выполняете матч на всей строке ( -x ) и распечатываете только строки, которые не соответствуют ( -v ). Поэтому вы печатаете строки в файлеA, которые не содержат тех же данных, что и любая строка в файлеB.

Недостатком этого решения является то, что он не учитывает порядок строк, и если ваш ввод имеет повторяющиеся строки в разных местах, вы можете не получить то, что ожидаете. Решением этого является использование реального инструмента сравнения, такого как diff . Вы можете сделать это, создав файл diff со значением контекста на 100% строк в файле, затем разберем его только для строк, которые будут удалены, если конвертировать файл A в файл B. (Примечание. Эта команда также удаляет diff форматирование после того, как он получит правильные строки.)

 diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC 

Ответ зависит от типа и формата файлов, которые вы сравниваете.

Если файлы, которые вы сравниваете, являются отсортированными текстовыми файлами, тогда инструмент GNU, написанный Ричардом Столлманом и Davide McKenzie, называется comm может выполнить фильтрацию, которую вы используете. Это часть ядра.

пример

Скажем, у вас есть следующие 2 файла:

 $ cat a 1 2 3 4 5 $ cat b 1 2 3 4 5 6 

Строки в файле b , которые не находятся в файле a :

 $ comm <(sort a) <(sort b) -3 6 

из stackoverflow …

comm -23 file1 file2

-23 подавляет строки, которые находятся в обоих файлах, или только в файле 2. Файлы нужно сортировать (они есть в вашем примере), но если нет, сначала проведите их через сортировку …

См. Справочную страницу здесь

Методы grep и comm (с сортировкой) занимают много времени на больших файлах. SiegeX и ghostdog74 разделяли два больших awk-метода для извлечения строк, уникальных для одного из двух файлов, на Stack Overflow:

 $ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2 $ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2 

Если файлы большие, и у вас нет пользовательского порядка для ваших записей, grep занимает слишком много времени. Быстрая альтернатива

 sort file1 > 1 sort file2 > 2 diff 1 2 | grep "\>" | sed -e 's/> //' 

[file2-file1 результаты на экран, канал в файл и т. д.]

Изменение > на < получило бы противоположное вычитание. rm 1 2

Вы также можете рассмотреть vimdiff, он подчеркивает различия между файлами в редакторе vim