Найти строки из файла, которые отсутствуют в другом файле [дубликат]
этот вопрос уже есть ответ здесь:
у меня есть два файла (скажем a.txt
и b.txt
), оба из которых имеют список имен. Я уже бежал sort
на обоих файлах.
теперь я хочу найти строки из a.txt
которых нет в b.txt
.
(Я потратил много времени, чтобы найти ответ на этот вопрос, так документирования его для дальнейшего использования)
4 ответов
команда, которую вы должны использовать, не diff
но comm
comm -23 a.txt b.txt
по умолчанию comm
выводит 3 столбца:осталось только, право-только, и. The -1
, -2
и -3
переключатели подавляют эти столбцы.
и -23
скрыть право-только и и столбцы, показывающие строки, которые отображаются только в первом (левом) файле.
если вы хотите найти строки которые появляются в обоих, вы можете использовать -12
, который скрывает осталось только и право-только столбцы, оставляя вас только с и.
простой ответ не сработал для меня, потому что я не понял comm
соответствует строке для строки, поэтому повторяющиеся строки в одном файле будут напечатаны как не существующие в другом. Например, если file1 содержит:
Alex
Bill
Fred
и file2 содержит:
Alex
Bill
Bill
Bill
Fred
затем comm -13 file1 file2
выводит:
Bill
Bill
в моем случае я хотел знать только, что каждая строка в file2 существует в file1, независимо от того, сколько раз эта строка произошла в каждом файл.
Решение 1: использовать -u
(уникальный) флаг sort
:
comm -13 <(sort -u file1) <(sort -u file2)
решение 2: (первый "рабочий" ответ, который я нашел) из unix.клиент StackExchange:
fgrep -v -f file1 file2
обратите внимание, что если file2 содержит повторяющиеся строки, которые вообще не существуют в file1,fgrep
выведет каждую из повторяющихся строк. Также обратите внимание, что мои совершенно ненаучные тесты на одном ноутбуке для одного (довольно большого) набора данных показано Решение 1 (используя comm
) почти в 5 раз быстрее, чем решение 2 (используя fgrep
).
Я не уверен, почему это было сказано diff
Не следует использовать. Я бы использовал его для сравнения двух файлов, а затем выводил только строки, которые находятся в левом файле, но не в правом. Такие линии помечены diff с <
поэтому достаточно grep этот символ в начале строки
diff a.txt b.txt | grep \^\<
в случае, если файлы еще не будут отсортированы, вы можете использовать:
comm -23 <(sort a.txt) <(sort b.txt)