Как сравнить два файла и строки вывода, которые не появляются в первом?

336
Zhro

Если у меня есть файл, Aсодержащий список полей:

2017-04-23 2017-04-30 2017-05-07 2017-05-14 2017-05-21 2017-05-28 2017-06-04 2017-06-11 2017-06-18 2017-06-25 

И еще один файл, Bсодержащий список полей:

2017-04-23 2017-04-30 2017-05-07 2017-05-14 2017-05-21 2017-05-28 2017-06-04 2017-06-11 2017-06-18 2017-06-25 2017-07-02 2017-07-09 2017-07-16 2017-07-23 

Как я могу быстро различить эти два файла, где я хочу знать все поля в файле, Bкоторых нет в файле A?

Это не обычный diff, где я хочу видеть относительную разницу между файлами, а скорее сравнение хешей, где каждая строка является записью на карте. Я хочу получить список всех строк в файле, Bкоторые отсутствуют в файле, Aтак что я могу удалить их, где каждая строка в файле Aпредставляет каталог, который должен быть сохранен.

Я ищу решение Bash / CoreUtils.

4

3 ответа на вопрос

3
Gohu

Если ваши файлы отсортированы, вы можете использовать comm :

$ comm -13 A B 2017-07-02 2017-07-09 2017-07-16 2017-07-23 

с вариантами:

  • -1: подавить столбец 1 (строки уникальные для FILE1)
  • -3: подавить столбец 3 (строки, которые появляются в обоих файлах)
И если они не отсортированы, вы можете отсортировать их с помощью подстановки процесса `<(sort filename)` Barmar 6 лет назад 1
2
Kamil Maciorowski

grep является правильным инструментом для работы, хотя это не Bash и не CoreUtils:

grep -Fxvf A B 

Все эти опции соответствуют POSIX. От man 1 grep:

-f pattern_file

Прочитайте один или несколько шаблонов из файла с именем по пути pattern_file. Шаблоны в pattern_fileдолжны заканчиваться символом. Нулевой шаблон может быть указан пустой строкой в ​​pattern_file. Если также не указан параметр -Eили -F, каждый шаблон должен рассматриваться как BRE, как описано в томе Базовых определений POSIX.1-2008, Раздел 9.3, Основные регулярные выражения.

-F

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

-v

Выберите линии, не соответствующие ни одному из указанных шаблонов. Если -vопция не указана, выбранные строки должны быть теми, которые соответствуют любому из указанных шаблонов.

-x

Рассматривайте только те входные строки, в которых используются все символы в строке, за исключением окончания, которое соответствует целой фиксированной строке или регулярному выражению, совпадающему со строками.

1
Paulo

Еще один способ с некоторыми трубами

cat A B|sort|uniq -u 

редактировать UUOC

Нет необходимости в кошке

sort A B|uniq -u 
Это относится к `A` и` B` одинаково, в то время как в исходной задаче эти файлы не являются взаимозаменяемыми. Что если в `A` есть строка, которой нет в` B`? Kamil Maciorowski 6 лет назад 0
@ Камил Да, ты прав. Я неправильно понял вопрос, он напечатает все строки, не дублированные в обоих файлах, а это не то, что хочет OP. Paulo 6 лет назад 0
Исправлено: `sort AAB | uniq -u`. :) Kamil Maciorowski 6 лет назад 1
Это работает :) Хорошее исправление. Но есть другая проблема с моим решением, вывод будет выглядеть отсортированным, может быть, это будет проблемой для целей OP. Paulo 6 лет назад 0
Вы читали последний абзац вопроса? Он просто хочет получить список каталогов для удаления, это не похоже на порядок вопросов. Кроме того, его входные файлы, кажется, отсортированы. Barmar 6 лет назад 0

Похожие вопросы