Как я могу заставить diff показывать только добавленные и удаленные строки? Если diff не может этого сделать, какой инструмент может?
diff A B | grep '^[<>]'
comm
.
Как я могу заставить diff показывать только добавленные и удаленные строки? Если diff не может этого сделать, какой инструмент может?
diff A B | grep '^[<>]'
comm
.
Ответы:
Еще один способ взглянуть на это:
Показать строки, которые существуют только в файле a: (то есть, что было удалено из a)
comm -23 a b
Показать строки, которые существуют только в файле b: (то есть, что было добавлено в b)
comm -13 a b
Показать строки, которые существуют только в одном или другом файле: (но не оба)
comm -3 a b | sed 's/^\t//'
(Предупреждение: если в файле a
есть строки, начинающиеся с TAB, он (первый TAB) будет удален из выходных данных.)
ПРИМЕЧАНИЕ. Оба файла должны быть отсортированы для comm
правильной работы. Если они еще не отсортированы, вы должны отсортировать их:
sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted
Если файлы очень длинные, это может быть довольно обременительным, поскольку требует дополнительной копии и, следовательно, вдвое больше дискового пространства.
comm -12 <(sort a) <(sort b)
comm
может делать то, что вы хотите. С его справочной страницы:
ОПИСАНИЕ
Сравните отсортированные файлы FILE1 и FILE2 построчно.
Без опций выведите три столбца. Первый столбец содержит строки, уникальные для FILE1, второй столбец содержит строки, уникальные для FILE2, а третий столбец содержит строки, общие для обоих файлов.
Эти столбцы подавляются с -1
, -2
и -3
соответственно.
Пример:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
И если вы просто хотите уникальные строки и не волнует, в каком файле они находятся:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
Как говорится в справочной странице, файлы должны быть отсортированы заранее.
Чтобы показать добавления и удаления без контекста, номера строк, +, -, <,>! и т.д., вы можете использовать diff следующим образом:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
Например, даны два файла:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
Следующая команда покажет строки, удаленные из a или добавленные в b:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
выход:
B-ONLY
A-ONLY
Эта немного другая команда покажет строки, удаленные из .txt:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
выход:
A-ONLY
Наконец, эта команда покажет строки, добавленные в .txt
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
выход
B-ONLY
Это то, что делает diff по умолчанию ... Может быть, вам нужно добавить несколько флагов, чтобы игнорировать пробелы?
diff -b -B
следует игнорировать пустые строки и различное количество пробелов.
Нет, на diff
самом деле не показывает различия между двумя файлами так, как можно подумать. Он создает последовательность команд редактирования для инструмента, который patch
можно использовать для изменения одного файла в другой.
Сложность любой попытки сделать то, что вы ищете, состоит в том, как определить, что представляет собой линию, которая изменилась, по сравнению с удаленной, за которой следует добавленная. Также, что делать, когда строки добавляются, удаляются и меняются рядом друг с другом.
diff
источники, но я, кажется, помню все виды вращений, чтобы отслеживать, где два файла совпадают, чтобы оставаться синхронизированными, и я думаю, что есть предел для отказа в зависимости от того, как далеко друг от друга линии есть. Но я не помню ни одного совпадения внутри строки, кроме (необязательно) свернутого пробела или игнорирования регистра. Или (возможно) слова на это влияют. В любом случае, это все, patch
и vgrep просто приходит на прогулку. Может быть. Во вторник.
Инструменты визуального сравнения объединяют два файла, так что сегмент с одинаковым количеством строк, но разным содержанием будет считаться измененным сегментом. Полностью новые линии между совпадающими сегментами считаются добавленными сегментами.
Так же работает инструмент командной строки sdiff , который показывает параллельное сравнение двух файлов в терминале. Измененные строки разделены | характер. Если строка существует только в файле A, <используется как символ-разделитель. Если строка существует только в файле B,> используется в качестве разделителя. Если в файлах нет символов <и>, вы можете использовать это для отображения только добавленных строк:
sdiff A B | grep '[<>]'
Спасибо senarvi, ваше решение (за которое не голосовали) фактически дало мне ТОЧНО то, что я хотел, после того, как искал целую вечность на тонне страниц.
Используя ваш ответ, вот что я придумал, чтобы получить список вещей, которые были изменены / добавлены / удалены. В этом примере используются 2 версии файла / etc / passwd и выводится имя пользователя для соответствующих записей.
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'
Я нахожу эту конкретную форму часто полезной:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
Пример:
printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
Выход:
-b
-c
+B
+C
-e
-f
+E
+F
Таким образом, он показывает старые строки с, -
за которыми сразу следует соответствующая новая строка с +
.
Если бы мы удалили C
:
printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
это выглядит так:
-b
+B
+C
-e
-f
+E
+F
Формат задокументирован по адресу man diff
:
--line-format=LFMT
format all input lines with LFMT`
а также:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
а также:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
Похожий вопрос: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux
Проверено в Ubuntu 18.04.
File1:
text670_1
text067_1
text067_2
File2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
Использование:
diff -y file1 file2
Это показывает две колонки для соответствующих файлов.
Выход:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1