Есть два файла с именем "a.txt" и "b.txt" , у обоих есть список слов. Теперь я хочу проверить, какие слова являются дополнительными в "a.txt" и не находятся в "b.txt" .
Мне нужен эффективный алгоритм, так как мне нужно сравнить два словаря.
Есть два файла с именем "a.txt" и "b.txt" , у обоих есть список слов. Теперь я хочу проверить, какие слова являются дополнительными в "a.txt" и не находятся в "b.txt" .
Мне нужен эффективный алгоритм, так как мне нужно сравнить два словаря.
Вот мое решение для этого:
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
Если у вас установлен vim, попробуйте следующее:
vimdiff file1 file2
или
vim -d file1 file2
вы найдете его фантастическим.
Отсортируйте их и используйте comm
:
comm -23 <(sort a.txt) <(sort b.txt)
comm
сравнивает (отсортированные) входные файлы и по умолчанию выводит три столбца: строки, которые являются уникальными для строк, которые являются уникальными для b, и строки, которые присутствуют в обоих. Указав -1
, -2
и/или -3
, вы можете отключить соответствующий вывод. Поэтому comm -23 a b
перечислены только записи, которые уникальны для a. Я использую синтаксис <(...)
для сортировки файлов на лету, если они уже отсортированы, вам это не нужно.
Попробуйте sdiff
(man sdiff
)
sdiff -s file1 file2
Вы можете использовать инструмент 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
Если вы предпочитаете стиль вывода 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.
Вы также можете использовать: 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
Кроме того, не забывайте о mcdiff - встроенной программе просмотра различий в GNU Midnight Commander.
Например:
mcdiff file1 file2
Наслаждайтесь!
Используйте comm -13
(требуется отсортированные файлы):
$ cat file1
one
two
three
$ cat file2
one
two
three
four
$ comm -13 <(sort file1) <(sort file2)
four
Используя 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