Здравствуйте, у меня есть два файла с именами файлов, которые выглядят так:
Файл 1:
123.txt
456.txt
789.txt
101112.txt
Файл 2:
123.txt
789.txt
101112.txt
Is там любая команда bash, которую я могу использовать для их перекрытия, и печатать только те строки или имена файлов, которые не совпадали. Поэтому я ожидаю что-то вроде этого:
456.txt
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
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
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
Простым подходом было бы использовать две команды «grep», каждая из которых берет один из файлов в виде списка строк для поиска в другом файле. Предполагая, что ваши файлы называются f1.txt и f2.txt:
grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt
Используемые опции grep следующие:
-F - использовать каждую строку как фиксированную строка, чтобы соответствовать, а не регулярное выражение -x - Только совпадение целых строк -v - Инвертировать совпадение для выбора несогласованных строк -f - Использовать файл, указанный в качестве аргумента, как список шаблонов в соответствии сЯ понимаю ваш вопрос, как вы хотите, чтобы все строки отображались только в одном из файлов, а не в обоих, и не учитывали порядок строк.
Я также предполагаю, что мы сравниваем файлы 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, которая содержит только уникальные значения и позволяет задавать операции, такие как «симметричная разность».
Обратите внимание, что с использованием обоих решений, если какой-либо из файлов содержит повторяющиеся строки, они игнорируются и обрабатываются только как одно вхождение.
Предполагая, что вам не нужно, чтобы результаты оставались в исходном порядке, просто используйте:
cat file1 file2 | sort | uniq -u
cat file1 file2
Выводит оба файла на стандартный вывод один за другим.
sort
Сортирует комбинированное содержимое двух файлов. Полезный побочный эффект, который нам интересен, заключается в том, что это ставит идентичные строки из обоих файлов рядом друг с другом.
uniq -u
Выводит только строки, которые являются «уникальными», то есть только один раз. Довольно раздражающе это смотрит только на пары смежных линий, поэтому необходима предыдущая команда sort.
Вы также можете использовать uniq -d для вывода только строк, которые происходят дважды. Это даст вам строки, которые являются общими для обоих файлов.
ПРИМЕЧАНИЕ. Я не уверен, насколько хорошо это решение работает, если одни и те же строки встречаются более одного раза в одном файле.
Простым подходом было бы использовать две команды «grep», каждая из которых берет один из файлов в виде списка строк для поиска в другом файле. Предполагая, что ваши файлы называются f1.txt и f2.txt:
grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt
Используемые опции grep следующие:
-F - использовать каждую строку как фиксированную строка, чтобы соответствовать, а не регулярное выражение -x - Только совпадение целых строк -v - Инвертировать совпадение для выбора несогласованных строк -f - Использовать файл, указанный в качестве аргумента, как список шаблонов в соответствии сЯ понимаю ваш вопрос, как вы хотите, чтобы все строки отображались только в одном из файлов, а не в обоих, и не учитывали порядок строк.
Я также предполагаю, что мы сравниваем файлы 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, которая содержит только уникальные значения и позволяет задавать операции, такие как «симметричная разность».
Обратите внимание, что с использованием обоих решений, если какой-либо из файлов содержит повторяющиеся строки, они игнорируются и обрабатываются только как одно вхождение.
Предполагая, что вам не нужно, чтобы результаты оставались в исходном порядке, просто используйте:
cat file1 file2 | sort | uniq -u
cat file1 file2
Выводит оба файла на стандартный вывод один за другим.
sort
Сортирует комбинированное содержимое двух файлов. Полезный побочный эффект, который нам интересен, заключается в том, что это ставит идентичные строки из обоих файлов рядом друг с другом.
uniq -u
Выводит только строки, которые являются «уникальными», то есть только один раз. Довольно раздражающе это смотрит только на пары смежных линий, поэтому необходима предыдущая команда sort.
Вы также можете использовать uniq -d для вывода только строк, которые происходят дважды. Это даст вам строки, которые являются общими для обоих файлов.
ПРИМЕЧАНИЕ. Я не уверен, насколько хорошо это решение работает, если одни и те же строки встречаются более одного раза в одном файле.
Простым подходом было бы использовать две команды «grep», каждая из которых берет один из файлов в виде списка строк для поиска в другом файле. Предполагая, что ваши файлы называются f1.txt и f2.txt:
grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt
Используемые опции grep следующие:
-F - использовать каждую строку как фиксированную строка, чтобы соответствовать, а не регулярное выражение -x - Только совпадение целых строк -v - Инвертировать совпадение для выбора несогласованных строк -f - Использовать файл, указанный в качестве аргумента, как список шаблонов в соответствии сЯ понимаю ваш вопрос, как вы хотите, чтобы все строки отображались только в одном из файлов, а не в обоих, и не учитывали порядок строк.
Я также предполагаю, что мы сравниваем файлы 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, которая содержит только уникальные значения и позволяет задавать операции, такие как «симметричная разность».
Обратите внимание, что с использованием обоих решений, если какой-либо из файлов содержит повторяющиеся строки, они игнорируются и обрабатываются только как одно вхождение.
Предполагая, что вам не нужно, чтобы результаты оставались в исходном порядке, просто используйте:
cat file1 file2 | sort | uniq -u
cat file1 file2
Выводит оба файла на стандартный вывод один за другим.
sort
Сортирует комбинированное содержимое двух файлов. Полезный побочный эффект, который нам интересен, заключается в том, что это ставит идентичные строки из обоих файлов рядом друг с другом.
uniq -u
Выводит только строки, которые являются «уникальными», то есть только один раз. Довольно раздражающе это смотрит только на пары смежных линий, поэтому необходима предыдущая команда sort.
Вы также можете использовать uniq -d для вывода только строк, которые происходят дважды. Это даст вам строки, которые являются общими для обоих файлов.
ПРИМЕЧАНИЕ. Я не уверен, насколько хорошо это решение работает, если одни и те же строки встречаются более одного раза в одном файле.