Сравнение двух файлов в терминале linux

Есть два файла с именем "a.txt" и "b.txt" , у обоих есть список слов. Теперь я хочу проверить, какие слова являются дополнительными в "a.txt" и не находятся в "b.txt" .

Мне нужен эффективный алгоритм, так как мне нужно сравнить два словаря.

Ответ 1

Вот мое решение для этого:

mkdir temp
mkdir results
cp /usr/share/dict/american-english ~/temp/american-english-dictionary
cp /usr/share/dict/british-english ~/temp/british-english-dictionary
cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary
cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary
grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english
grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english
grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english

Ответ 2

Если у вас установлен vim, попробуйте следующее:

vimdiff file1 file2

или

vim -d file1 file2

вы найдете его фантастическим. enter image description here

Ответ 3

Отсортируйте их и используйте comm:

comm -23 <(sort a.txt) <(sort b.txt)

comm сравнивает (отсортированные) входные файлы и по умолчанию выводит три столбца: строки, которые являются уникальными для строк, которые являются уникальными для b, и строки, которые присутствуют в обоих. Указав -1, -2 и/или -3, вы можете отключить соответствующий вывод. Поэтому comm -23 a b перечислены только записи, которые уникальны для a. Я использую синтаксис <(...) для сортировки файлов на лету, если они уже отсортированы, вам это не нужно.

Ответ 4

Попробуйте sdiff (man sdiff)

sdiff -s file1 file2

Ответ 5

Вы можете использовать инструмент diff в Linux для сравнения двух файлов. Вы можете использовать параметры --changed-group-format и --unchanged-group-format для фильтрации необходимых данных.

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

  • '% & Л;' получить строки из FILE1

  • '%>' получить строки из FILE2

  • '' (пустая строка) для удаления строк из обоих файлов.

E.g: diff --changed-group-format="%<" --unchanged-group-format="" file1.txt file2.txt

[[email protected] tmp]# cat file1.txt 
test one
test two
test three
test four
test eight
[[email protected] tmp]# cat file2.txt 
test one
test three
test nine
[[email protected] tmp]# diff --changed-group-format='%<' --unchanged-group-format='' file1.txt file2.txt 
test two
test four
test eight

Ответ 6

Если вы предпочитаете стиль вывода diff из git diff, вы можете использовать его с флагом --no-index для сравнения файлов, отсутствующих в репозитории git:

git diff --no-index a.txt b.txt

Используя пару файлов, каждая из которых содержит около 200 тыс. строк имен файлов, я сравнил (со встроенной командой time) этот подход по сравнению с некоторыми другими ответами здесь:

git diff --no-index a.txt b.txt
# ~1.2s

comm -23 <(sort a.txt) <(sort b.txt)
# ~0.2s

diff a.txt b.txt
# ~2.6s

sdiff a.txt b.txt
# ~2.7s

vimdiff a.txt b.txt
# ~3.2s

comm, кажется, самый быстрый на данный момент, в то время как git diff --no-index, кажется, самый быстрый подход для вывода в стиле diff.


Обновление 2018-03-25 На самом деле вы можете опустить флаг --no-index, если вы не находитесь внутри репозитория git и не хотите сравнивать неотслеживаемые файлы в этом репозитории. Из справочных страниц:

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

Ответ 7

Вы также можете использовать: colordiff: отображает вывод diff с цветами.

О vimdiff. Он позволяет сравнивать файлы через SSH, например:

vimdiff /var/log/secure scp://192.168.1.25/var/log/secure

Извлечено из: http://www.sysadmit.com/2016/05/linux-diferencias-entre-dos-archivos.html

Ответ 8

Кроме того, не забывайте о mcdiff - встроенной программе просмотра различий в GNU Midnight Commander.

Например:

mcdiff file1 file2

Наслаждайтесь!

Ответ 9

Используйте comm -13 (требуется отсортированные файлы):

$ cat file1
one
two
three

$ cat file2
one
two
three
four

$ comm -13 <(sort file1) <(sort file2)
four

Ответ 10

Используя awk для этого. Тестовые файлы:

$ cat a.txt
one
two
three
four
four
$ cat b.txt
three
two
one

The awk:

$ awk '
NR==FNR {                    # process b.txt  or the first file
    seen[$0]                 # hash words to hash seen
    next                     # next word in b.txt
}                            # process a.txt  or all files after the first
!($0 in seen)' b.txt a.txt   # if word is not hashed to seen, output it

Дубликаты выдаются:

four
four

Чтобы избежать дубликатов, добавьте каждое вновь встреченное слово в текстовом формате в хэш seen:

$ awk '
NR==FNR {
    seen[$0]
    next
}
!($0 in seen) {              # if word is not hashed to seen
    seen[$0]                 # hash unseen a.txt words to seen to avoid duplicates 
    print                    # and output it
}' b.txt a.txt

Выход:

four

Если списки слов разделены запятыми, например:

$ cat a.txt
four,four,three,three,two,one
five,six
$ cat b.txt
one,two,three

вы должны сделать пару дополнительных кругов (for циклы):

awk -F, '                    # comma-separated input
NR==FNR {
    for(i=1;i<=NF;i++)       # loop all comma-separated fields
        seen[$i]
    next
}
{
    for(i=1;i<=NF;i++)
        if(!($i in seen)) {
             seen[$i]        # this time we buffer output (below):
             buffer=buffer (buffer==""?"":",") $i
        }
    if(buffer!="") {         # output unempty buffers after each record in a.txt
        print buffer
        buffer=""
    }
}' b.txt a.txt

На этот раз выведите:

four
five,six