сравнить содержание двух текстовых файлов в человечности?

Я должен сравнить содержание текстовых файлов (в целом и не мудрый строкой как различная команда) и распечатать недостающий текст. Существует ли команда, чтобы сделать так?Заранее спасибо.

Править: Как пример, скажите, что file1 имеет:

1 2 3
4 5

файл 2 имеет:

1 5
2 3 4 6

Я хочу сравнить эти файлы и печать, как произведено:

6

Команда diff сравнивает текстовые файлы линию за линией, в этом случае, почти весь файл будет распечатан. (Мои фактические файлы более сложны и длинны, таким образом, я даю простой пример.)

1
задан 27 February 2017 в 08:51

5 ответов

Другое решение (python):

def readFile(fi):
  return open(fi,"rb").read().decode(cod)
def process(text):
  return text.replace("\n"," ").split(" ")

print(set([x for x in process(readFile(file1,"utf-8")) if not x==""]).difference(set([x for x in process(readFile(file2,"utf-8")) if not x==""])))
0
ответ дан 3 December 2019 в 06:38

Я приму следующее: Ваши файлы состоят из данных, которые или разделяются с пространством или новой строкой, И Вы не заботитесь о знании, где данные отсутствуют (или знайте, что это всегда, например, в file2).

то, Что мы сделаем, просто: Замените каждое пространство новой строкой в обоих файлах, свяжите их, затем ищите единственные (уникальные) записи только:

sort <( tr ' ' '\n' < file1 ) <(tr ' ' '\n' < file2) | uniq -u
0
ответ дан 3 December 2019 в 06:38

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

awk -v RS='[[:space:]]+' 'FNR==NR {a[$0]++; next} {a[$0]--} END {for (i in a) if (a[i] != 0) print i}' file1 file2

Здесь:

  • -v RS='[[:space:]]+' устанавливает разделитель записей (RS) на любой пробел, таким образом, вся каждая "строка" будет разделена любым пробелом (включая новые строки).
  • FNR == NR - FNR рекордное число (NR) (или, номер строки, если Вы будете) для текущего файла, и NR полный номер строки во всех входных файлах. Так, каждый раз, когда эти два равны, мы имеем дело с первым файлом.
  • {a[$0]++; next} - набор и инкремент количество появлений текущей "строки", затем переместитесь в следующую строку, не обрабатывая, больше управляет. Этот блок только выполняется для первого файла, таким образом, эффект состоит в том, что это правило относится к строкам из первого файла, и следующий блок относится всем другим файлам.
  • {a[$0]--}, постепенно уменьшите количество появлений текущей "строки".
  • END {for (i in a) if (a[i] != 0) print i} - в конце всего входа, для каждой записи в массиве a, распечатайте ту запись, если количество появлений не 0. Так, любая "строка", которая была замечена равное количество раз в обоих файлах, будет пропущена.
4
ответ дан 3 December 2019 в 06:38

Это - другое решение:

comm -3 <( cat file1 | tr ' \t' '\n' | sort) <(cat file2 | tr ' \t' '\n' | sort) | sort -u

где:

  • tr ' \t' '\n' | sort замените пространство и вкладку с новой строкой, и переупорядочьте результат
  • comm Сравнивает отсортированные файлы file1 и file2 линию за линией, и с -3 опция подавляет строки, которые появляются в обоих файлах
  • sort -u наконец, удаляет дублирующиеся строки, это необходимо в случае дублирующегося маркера

В этом случае tr ' ' '\n' | sort вывод используется в качестве стандартного входа для comm команда.

1
ответ дан 3 December 2019 в 06:38

Подготовка файлов

Если я понимаю правильно, Вы хотите распечатать уникальные числа или слова в сравнении. Я преобразовал бы файлы так, чтобы каждое число/слово имело собственную строку, отсортируйте их, удалите пустые строки и дубликаты и после этого сравните файлы.

Я предполагаю, что пробелы разделяют числа или слова. Для каждого файла

< file-x.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -u > file-x.1

Посмотрите man tr для деталей.

Если Вы хотите отсортировать численно, можно добавить опцию -n или -h в зависимости от числового формата. Посмотрите man sort для деталей.

Пример Вашего исходного вопроса,

В примере исходного вопроса я использовал бы -n,

< file-x.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-x.1

где x может быть a и b для этих двух файлов для сравнения, так например,

< file-a.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-a.1
< file-b.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-b.1

Можно осмотреть эти преобразованные и отсортированные файлы, если Вы желаете.

Наконец сравните файлы со следующей командной строкой,

$ diff file-a.1 file-b.1
5a6
> 6

Это определяет число, которое только найдено во втором файле Вашего демонстрационного входа от исходного вопроса. Посмотрите man diff для получения дополнительной информации если Вы хотите измененный вывод от diff.

Мой пример

Это - пример с уникальным числом в каждом из файлов.

$ echo '1 2 3 4 5'>file-c.orig
$ echo '2 3 4 5 6'>file-d.orig
$ < file-c.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-c.1
$ < file-d.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-d.1
$ diff  file-c.1 file-d.1
1d0
< 1
5a5
> 6

Это определяет

  • '1', который только найден в 1-м файле, обозначенном' <'
  • '6', который только найден в 2-м файле, обозначенном'>'

Пример в комментарии Lety

Например: file1 = 1 3 1 4 5 и file2 = 5 1 4 3 6, ожидаемый вывод: 1 6.

$ echo '1 3 1 4 5'>file-e.orig
$ echo '5 1 4 3 6'>file-f.orig

$ < file-e.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-e.1
$ < file-f.orig tr ' ' '\n' | tr -s '\n' '\n' |sort -nu > file-f.1
$ diff  file-e.1 file-f.14a5
> 6

$ comm -3 <( cat file-e.orig | tr ' \t' '\n' | sort) <(cat file-f.orig | tr ' \t' '\n' | sort) | sort -u
1
    6

$ awk -v RS='[[:space:]]+' 'FNR==NR {a[$0]++; next} {a[$0]--} END {for (i in a) if (a[i] != 0) print i}' file-e.orig file-f.orig
1
6

В этом случае мой метод показывает другой результат по сравнению с методами @Lety и @muru. Давайте ожидать OP, @samhitha, давайте скажем нам, что является желаемым выводом сравнения.

0
ответ дан 3 December 2019 в 06:38

Другие вопросы по тегам:

Похожие вопросы: