Я хочу сравнить файл1 с файлом 2 и сгенерировать файл3, который содержит строки в файле1, которых нет в файле2.
Сравните два файла по строкам и создайте разницу в другом файле
Ответ 1
diff (1) не является ответом, но comm (1) есть.
NAME
comm - compare two sorted files line by line
SYNOPSIS
comm [OPTION]... FILE1 FILE2
...
-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
Итак,
comm -2 -3 file1 file2 > file3
Входные файлы должны быть отсортированы. Если это не так, сначала сортируйте их. Это можно сделать с помощью временного файла или...
comm -2 -3 <(sort file1) <(sort file2) > file3
при условии, что ваша оболочка поддерживает замещение процесса (bash делает).
Ответ 2
Утилита Unix diff
предназначена именно для этой цели.
$ diff -u file1 file2 > file3
См. руководство и Интернет для параметров, разных форматов вывода и т.д.
Ответ 3
Рассмотрим это:
file a.txt:
abcd
efgh
файл b.txt:
abcd
Вы можете найти разницу:
diff -a --suppress-common-lines -y a.txt b.txt
Выход будет:
efgh
Вы можете переназначить вывод в выходном файле (c.txt), используя:
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
Это ответит на ваш вопрос:
"... который содержит строки в файле1, которые не присутствует в файле2."
Ответ 4
Иногда diff
- это полезная утилита, но иногда подходит join
. Файлы должны быть предварительно отсортированы или, если вы используете оболочку, которая поддерживает замещение процесса, например bash, ksh или zsh, вы можете выполнить сортировку на лету.
join -v 1 <(sort file1) <(sort file2)
Ответ 5
Попробуйте
sdiff file1 file2
В большинстве случаев он работает намного лучше для меня. Вы можете захотеть отсортировать файлы ранее, если порядок строк не важен (например, некоторые текстовые файлы конфигурации).
Например,
sdiff -w 185 file1.cfg file2.cfg
Ответ 6
Если вам нужно решить это с помощью coreutils, то принятый ответ хорош:
comm -23 <(sort file1) <(sort file2) > file3
Вы также можете использовать sd (поток diff), который не требует сортировки и замены процесса и поддерживает бесконечные потоки, например
cat file1 | sd 'cat file2' > file3
Вероятно, не так много пользы для этого примера, но все же его рассматривайте; в некоторых случаях вы не сможете использовать comm
и grep -F
и diff
.
Здесь blogpost Я написал о различных потоках на терминале, который вводит sd.
Ответ 7
Уже много ответов, но ни один из них не идеален ИМХО. Ответ Thanatos оставляет некоторые дополнительные символы в строке, а ответ Сорпигаля требует, чтобы файлы сортировались или предварительно сортировались, что может быть неприемлемым при любых обстоятельствах.
Я думаю, что лучший способ получить линии, которые отличаются друг от друга, и ничего больше (никаких дополнительных символов, без повторного упорядочения) - это комбинация diff
, grep
и awk
(или подобных).
Если строки не содержат "<", короткий однострочный шрифт может быть:
diff urls.txt* | grep "<" | sed 's/< //g'
но это приведет к удалению из строк всех экземпляров "<" (меньше, пробела), что не всегда нормально (например, исходный код). Самый безопасный вариант - использовать awk:
diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
Этот однострочный шрифт разграничивает оба файла, затем отфильтровывает выходной поток diff в стиле ed, а затем удаляет конечный "<" этот diff добавляет. Это работает, даже если строки содержат некоторое число "<" самих себя.
Ответ 8
Используйте утилиту Diff и извлекайте только строки, начинающиеся с < на выходе
Ответ 9
diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt
Я попробовал почти все ответы в этой теме, но ни один из них не был завершен. После нескольких трасс над мной работало. diff даст вам разницу, но с некоторыми нежелательными специальными символами. где фактические разностные линии начинаются с ' > '. поэтому следующий шаг: строки grep начинаются с ' > ', а затем удаляются с помощью sed.
Ответ 10
Тем не менее, нет решения grep
?
-
строки, которые существуют только в file2:
grep -Fxvf file1 file2 > file3
-
строки, которые существуют только в file1:
grep -Fxvf file2 file1 > file3
-
строки, которые существуют в обоих файлах:
grep -Fxf file1 file2 > file3
Ответ 11
Вы можете использовать diff
со следующим форматированием вывода:
diff --old-line-format='' --unchanged-line-format='' file1 file2
--old-line-format=''
, отключить вывод для file1, если строка отличалась, сравнить в file2. --unchanged-line-format=''
, отключить вывод, если строки были одинаковыми.
Ответ 12
Я удивлен, что никто не упомянул diff -y
, чтобы создавал параллельный вывод, например:
diff -y file1 file2 > file3
И в file3
(в разных строках есть символ |
посередине):
same same
diff_1 | diff_2