Перекрытие / Сравнение двух файлов и печать того, что не соответствует

Здравствуйте, у меня есть два файла с именами файлов, которые выглядят так:

Файл 1:

123.txt 456.txt 789.txt 101112.txt

Файл 2:

123.txt 789.txt 101112.txt

Is там любая команда bash, которую я могу использовать для их перекрытия, и печатать только те строки или имена файлов, которые не совпадали. Поэтому я ожидаю что-то вроде этого:

456.txt
7
задан 15 January 2018 в 13:39

12 ответов

comm является вашим другом здесь:

Если файлы уже отсортированы:

comm -3 f1.txt f2.txt

Если не отсортировано, sort и передать их в качестве файловых дескрипторов, использующих процесс подстановка (так что нам не нужны временные файлы):

comm -3 <(sort f1.txt) <(sort f2.txt)

Пример:

% cat f1.txt
123.txt
456.txt
789.txt
101112.txt

% cat f2.txt
123.txt
789.txt
101112.txt

% comm -3 <(sort f1.txt) <(sort f2.txt)
456.txt
13
ответ дан 22 May 2018 в 15:31

comm является вашим другом здесь:

Если файлы уже отсортированы:

comm -3 f1.txt f2.txt

Если не отсортировано, sort и передать их в качестве файловых дескрипторов, использующих процесс подстановка (так что нам не нужны временные файлы):

comm -3 <(sort f1.txt) <(sort f2.txt)

Пример:

% cat f1.txt 123.txt 456.txt 789.txt 101112.txt % cat f2.txt 123.txt 789.txt 101112.txt % comm -3 <(sort f1.txt) <(sort f2.txt) 456.txt
13
ответ дан 17 July 2018 в 23:01

comm является вашим другом здесь:

Если файлы уже отсортированы:

comm -3 f1.txt f2.txt

Если не отсортировано, sort и передать их в качестве файловых дескрипторов, использующих процесс подстановка (так что нам не нужны временные файлы):

comm -3 <(sort f1.txt) <(sort f2.txt)

Пример:

% cat f1.txt 123.txt 456.txt 789.txt 101112.txt % cat f2.txt 123.txt 789.txt 101112.txt % comm -3 <(sort f1.txt) <(sort f2.txt) 456.txt
13
ответ дан 24 July 2018 в 13:34

Простым подходом было бы использовать две команды «grep», каждая из которых берет один из файлов в виде списка строк для поиска в другом файле. Предполагая, что ваши файлы называются f1.txt и f2.txt:

grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt

Используемые опции grep следующие:

-F - использовать каждую строку как фиксированную строка, чтобы соответствовать, а не регулярное выражение -x - Только совпадение целых строк -v - Инвертировать совпадение для выбора несогласованных строк -f - Использовать файл, указанный в качестве аргумента, как список шаблонов в соответствии с
3
ответ дан 22 May 2018 в 15:31
  • 1
    Хороший, лучше, чем мои петли. Я забыл, что grep также может читать выражения из файлов. Однако, вероятно, вы должны добавить -F, чтобы рассматривать выражения как фиксированные строки, а не как шаблоны регулярных выражений. – Byte Commander 15 January 2018 в 14:01
  • 2
    Я думал, что должен это сделать, не был уверен, что -x все еще будет необходимо в этом случае. – Arronical 15 January 2018 в 14:34

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

Я также предполагаю, что мы сравниваем файлы f1.txt и f2.txt. Вместо этого добавьте свои имена.

Используя Bash, вы можете сделать это с двумя циклами, где каждый обрабатывает один файл и проверяет каждую строку, если она появляется в другой. Этот подход не очень эффективен, но он должен работать:

# This loops over f1.txt and searches each line in f2.txt
while read line ; do grep -Fxqe "$line" f2.txt || echo "$line" ; done < f1.txt 

# This loops over f2.txt and searches each line in f1.txt
while read line ; do grep -Fxqe "$line" f1.txt || echo "$line" ; done < f2.txt 

Оба цикла вместе создают желаемый результат. Каждый для себя проверяет только строки в одном файле, которые не отображаются в другом.

Может быть написано более быстрое решение, например. с коротким однострочным Python:

python3 -c 's1=set(open("f1.txt")); s2=set(open("f2.txt")); print(*s1.symmetric_difference(s2), sep="")'

В нем используется структура данных Set, которая содержит только уникальные значения и позволяет задавать операции, такие как «симметричная разность».

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

2
ответ дан 22 May 2018 в 15:31

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

cat file1 file2 | sort | uniq -u

Объяснение:

cat file1 file2

Выводит оба файла на стандартный вывод один за другим.

sort

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

uniq -u

Выводит только строки, которые являются «уникальными», то есть только один раз. Довольно раздражающе это смотрит только на пары смежных линий, поэтому необходима предыдущая команда sort.

Вы также можете использовать uniq -d для вывода только строк, которые происходят дважды. Это даст вам строки, которые являются общими для обоих файлов.

ПРИМЕЧАНИЕ. Я не уверен, насколько хорошо это решение работает, если одни и те же строки встречаются более одного раза в одном файле.

0
ответ дан 22 May 2018 в 15:31

Простым подходом было бы использовать две команды «grep», каждая из которых берет один из файлов в виде списка строк для поиска в другом файле. Предполагая, что ваши файлы называются f1.txt и f2.txt:

grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt

Используемые опции grep следующие:

-F - использовать каждую строку как фиксированную строка, чтобы соответствовать, а не регулярное выражение -x - Только совпадение целых строк -v - Инвертировать совпадение для выбора несогласованных строк -f - Использовать файл, указанный в качестве аргумента, как список шаблонов в соответствии с
3
ответ дан 17 July 2018 в 23:01

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

Я также предполагаю, что мы сравниваем файлы f1.txt и f2.txt. Вместо этого добавьте свои имена.

Используя Bash, вы можете сделать это с двумя циклами, где каждый обрабатывает один файл и проверяет каждую строку, если она появляется в другой. Этот подход не очень эффективен, но он должен работать:

# This loops over f1.txt and searches each line in f2.txt while read line ; do grep -Fxqe "$line" f2.txt || echo "$line" ; done < f1.txt # This loops over f2.txt and searches each line in f1.txt while read line ; do grep -Fxqe "$line" f1.txt || echo "$line" ; done < f2.txt

Оба цикла вместе создают желаемый результат. Каждый для себя проверяет только строки в одном файле, которые не отображаются в другом.

Может быть написано более быстрое решение, например. с коротким однострочным Python:

python3 -c 's1=set(open("f1.txt")); s2=set(open("f2.txt")); print(*s1.symmetric_difference(s2), sep="")'

В нем используется структура данных Set, которая содержит только уникальные значения и позволяет задавать операции, такие как «симметричная разность».

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

2
ответ дан 17 July 2018 в 23:01

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

cat file1 file2 | sort | uniq -u

Объяснение:

cat file1 file2

Выводит оба файла на стандартный вывод один за другим.

sort

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

uniq -u

Выводит только строки, которые являются «уникальными», то есть только один раз. Довольно раздражающе это смотрит только на пары смежных линий, поэтому необходима предыдущая команда sort.

Вы также можете использовать uniq -d для вывода только строк, которые происходят дважды. Это даст вам строки, которые являются общими для обоих файлов.

ПРИМЕЧАНИЕ. Я не уверен, насколько хорошо это решение работает, если одни и те же строки встречаются более одного раза в одном файле.

1
ответ дан 17 July 2018 в 23:01

Простым подходом было бы использовать две команды «grep», каждая из которых берет один из файлов в виде списка строк для поиска в другом файле. Предполагая, что ваши файлы называются f1.txt и f2.txt:

grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt

Используемые опции grep следующие:

-F - использовать каждую строку как фиксированную строка, чтобы соответствовать, а не регулярное выражение -x - Только совпадение целых строк -v - Инвертировать совпадение для выбора несогласованных строк -f - Использовать файл, указанный в качестве аргумента, как список шаблонов в соответствии с
3
ответ дан 24 July 2018 в 13:34
  • 1
    Хороший, лучше, чем мои петли. Я забыл, что grep также может читать выражения из файлов. Однако, вероятно, вы должны добавить -F, чтобы рассматривать выражения как фиксированные строки, а не как шаблоны регулярных выражений. – Byte Commander 15 January 2018 в 14:01
  • 2
    Я думал, что должен это сделать, не был уверен, что -x все еще будет необходимо в этом случае. – Arronical 15 January 2018 в 14:34

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

Я также предполагаю, что мы сравниваем файлы f1.txt и f2.txt. Вместо этого добавьте свои имена.

Используя Bash, вы можете сделать это с двумя циклами, где каждый обрабатывает один файл и проверяет каждую строку, если она появляется в другой. Этот подход не очень эффективен, но он должен работать:

# This loops over f1.txt and searches each line in f2.txt while read line ; do grep -Fxqe "$line" f2.txt || echo "$line" ; done < f1.txt # This loops over f2.txt and searches each line in f1.txt while read line ; do grep -Fxqe "$line" f1.txt || echo "$line" ; done < f2.txt

Оба цикла вместе создают желаемый результат. Каждый для себя проверяет только строки в одном файле, которые не отображаются в другом.

Может быть написано более быстрое решение, например. с коротким однострочным Python:

python3 -c 's1=set(open("f1.txt")); s2=set(open("f2.txt")); print(*s1.symmetric_difference(s2), sep="")'

В нем используется структура данных Set, которая содержит только уникальные значения и позволяет задавать операции, такие как «симметричная разность».

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

2
ответ дан 24 July 2018 в 13:34

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

cat file1 file2 | sort | uniq -u

Объяснение:

cat file1 file2

Выводит оба файла на стандартный вывод один за другим.

sort

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

uniq -u

Выводит только строки, которые являются «уникальными», то есть только один раз. Довольно раздражающе это смотрит только на пары смежных линий, поэтому необходима предыдущая команда sort.

Вы также можете использовать uniq -d для вывода только строк, которые происходят дважды. Это даст вам строки, которые являются общими для обоих файлов.

ПРИМЕЧАНИЕ. Я не уверен, насколько хорошо это решение работает, если одни и те же строки встречаются более одного раза в одном файле.

1
ответ дан 24 July 2018 в 13:34

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

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