Как получить разницу между файлами

Как получить разницу между файлами

Я нашел другие ссылки в сообществах StackOverflow, которые были похожи, но они не дали точного ответа на мой вопрос.

У меня есть 2 файла с разным количеством строк, НО я отсортировал их оба. Мои исходные файлы состоят из сотен строк, но для устранения неполадок я сделал file1 с 12 строками, а file2 — с 5 строками. File2 — это подмножество file1. Я хочу запустить команду, которая выведет все строки, которые есть в file1, но которых нет в file2.

Я пробовал использовать команды Unix diff, commно они обе выводят полное содержимое файла file1, а это не то, что мне нужно.

Вот краткий пример:

File1      File2
A           B
B           E
C           I
E           N
G           O
I
L
M
N
O
X

Итак, здесь мы видим, что все, что есть в file2, есть в file1. По какой-то причине, diffи commоба показали полное содержимое file1. Я предполагаю, это потому, что он делает построчное сравнение, а не ищет по всему файлу.

Есть ли другая команда Unix, которую я могу запустить и которая выведет то, что я ожидаю?

EDIT: Команды, которые я использовал, чтобы попытаться получить то, что мне было нужно, были:

а) diff файл1 файл2

Это в основном перечислило все из file1 с < перед ним, показывающим, что содержимое было из file1, и все из file2 с > перед ним. Определенно не то, что мне было нужно

б) комм -23 файл1 файл2

Это снова показало все содержимое file1, а не разницу, как я ожидал. Я также

в) комм -3 файл1 файл2

На странице справки comm говорилось, что это выведет строки в файле 1, но не в файле 2, и наоборот, но это также не показало того, что я хотел, потому что в моем примере B появляется в обоих файлах, но на разных строках. Однако вывод думает, что он есть в одном, но не в другом, и поэтому выводит его. Поэтому вывод выглядел так:

A
B
    B
C
E
    E
etc.

И это было не то, чего я ожидал. Я ожидал

A
C
G
L
M
X

решение1

Вы можете просто выполнить обратный grep содержимого файла b в файле A, чтобы сделать это

пример :

francois@zaphod:/tmp$
 cat > A
az
ae
ar
at
ay
au
francois@zaphod:/tmp$
 cat > b
ba
by
ay
at
au
francois@zaphod:/tmp$
  grep -v "$(cat /tmp/b)" /tmp/A
az
ae
ar
francois@zaphod:/tmp$

здесь выводится только строка файла A, не существующая в файле b

решение2

Вывод Diff показывает, что необходимо сделать, чтобы файл X стал файлом Y.

Согласно вашему комментарию, вы могли бы использовать следующую однострочник:

cat x y | sort -u  | cat y - | sort | uniq -u

Это будет

  1. Прочитать оба файла
  2. Пересортируйте их и выведите только уникальные строки ( -uв сортировке)
  3. Прочитайте файл (y) и объедините его с переданным выводом
  4. Курортный выход
  5. -uИспользуйте uniq, чтобы использовались только строки, представленные один раз ( в unique).

Этот метод основан на теории множеств. Сначала вы складываете два множества, а затем вычитаете одно из них.

решение3

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

Я ожидаю следующий вывод, comm -3 file1 file2когда file1это текстовый файл Unix, а file2это текстовый файл DOS (это то, что у вас есть):

A
B
        B
C
E
        E
G
I
        I
L
M
N
        N
O
        O
X

Я ожидаю следующий вывод, comm -3 file1 file2когда file1это текстовый файл DOS, а file2это текстовый файл Unix:

A
        B
B
C
        E
E
G
        I
I
L
M
        N
N
        O
O
X

Если оба файла имеют одинаковое окончание строк, т. е. оба являются текстовыми файлами DOS или оба являются текстовыми файлами Unix, я ожидаю, что вывод comm -3 file1 file2будет следующим:

A
C
G
L
M
X

Вы можете преобразовать оба файла в текстовый формат Unix с помощью команды

dos2unix file1 file2

... при условии, что у вас dos2unixустановлена ​​утилита.

Связанный контент