Как сравнить два разных файла построчно в Unix?


13

File1:

123
234
345
456

File2:

123
234
343
758

Ожидаемый результат: File3:

TRUE
TRUE
FALSE
FALSE

поэтому код должен сравнить два файла и вывести «TRUE», если он совпадает, иначе он должен вывести «FALSE» в новом файле. Может ли кто-нибудь предоставить решение для этого?


10
Что произойдет, если два файла имеют разную длину? С какой частью решения этой проблемы у вас возникают проблемы?
Кусалананда

9
Возможно, вы захотите взглянуть на diff.
Панки

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

1
@GiacomoAlzetta Дело в том, commчто он требует сортированного ввода. Помимо того , что пример в этом вопросе действительно отсортировали вход, вопрос никогда не утверждает , что это фактические данные, которые используются и никогда не говорит ничего о упорядочивания данных.
Кусалананда

2
Уловка αғsнιη nlполезна commдля наложения сортировки на файлы.
Гленн Джекман

Ответы:


56

Используйте diffкоманду следующим образом, в bashлюбой другой оболочке, которая поддерживает <(...) подстановки процессов, или вы можете эмулировать ее, как показано здесь :

diff --new-line-format='FALSE'$'\n' \
     --old-line-format='' \
     --unchanged-line-format='TRUE'$'\n' \
<(nl file1) <(nl file2)

Выход будет:

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\nвыведите, FALSEесли строки были разными, и --old-line-format=''мы отключаем вывод, если строка отличалась для file1, который известен как старая команда file to diff (мы также можем поменять их местами, что означает, что один из них должен печатать FALSEдругой, должен быть отключен).

--unchanged-line-format='TRUE'$'\n'выведите, TRUEесли строки были одинаковыми. $'\n'побега синтаксис С-типа используется для печати на новую строку после каждого линейного выхода.


24

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

$ paste file1 file2 | awk -F '\t' '{ print ($1 == $2 ? "TRUE" : "FALSE") }'
TRUE
TRUE
FALSE
FALSE

Используется pasteдля создания двух столбцов с разделителями табуляции, с содержимым двух файлов в каждом столбце. Команда awkсравнивает два столбца в каждой строке и печатает, TRUEесли столбцы совпадают, и печатает иначе FALSE.


10

Предполагая, что оба файла имеют одинаковое количество строк:

awk '{getline f2 < "file2"; print f2 == $0 ? "TRUE" : "FALSE"}' file1

Это делает числовое сравнение, если строки для сравнения являются числами и лексическими в противном случае. Например, 100и 1.0e2будет считаться идентичным. Изменить наf2"" == $0 принудительное лексическое сравнение в любом случае.

В зависимости от awkреализации, лексическое сравнение будет выполняться как при использовании memcmp()(межбайтовое сравнение), или как при использовании strcoll()(независимо от того, сортируются ли две строки одинаково в порядке сортировки локали). Это может иметь значение в некоторых локалях, где порядок не определен для некоторых символов, а не для всех вводимых десятичных цифр, как в вашем примере.


7

Python 3

with open('file1') as file1, open('file2') as file2:
    for line1, line2 in zip(file1, file2):
        print(line1 == line2)

Выход:

True
True
False
False

Если вам нужно TRUEи FALSEзаглавными буквами, замените строку печати одним из следующих:

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')

2
В Python 2 import itertoolsсначала выполните , а затем используйте itertools.izipвместо zip. В противном случае он будет считывать оба файла в память, возможно, используя слишком много памяти.
Очки

4

В bash, чтение из каждого файла в whileцикле, сравнение строк чтения и печати TRUEили FALSEсоответственно:

while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
    [[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2

Два вызова для readчтения из файлового дескриптора 3 и 4 соответственно. Файлы перенаправляются на них с двумя входными перенаправлениями в цикл.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.