Як порівняти два різних файли по рядку в unix?


13

Файл1:

123
234
345
456

Файл2:

123
234
343
758

Очікуваний вихід: File3:

TRUE
TRUE
FALSE
FALSE

тому код повинен порівнювати два файли та друкувати "TRUE", якщо він відповідає іншому, він повинен надрукувати "FALSE" у новому файлі. Може хто-небудь, будь ласка, надати рішення для цього?


10
Що станеться, якщо два файли мають неоднакову довжину? З якою частиною вирішення цього питання у вас виникають проблеми?
Kusalananda

9
Можливо, ви захочете поглянути diff.
Панки

2
Інша корисна команда в цих ситуаціях - це comm. Це дозволяє легко перераховувати рядки, які мають обидва файли спільних або є унікальними для одного чи іншого.
Джакомо Альзетта

1
@GiacomoAlzetta Справа в commтому, що він потребує впорядкованого введення. Крім того , що приклад в цьому питанні дійсно відсортували вхід, питання ніколи не стверджує , що це фактичні дані, які використовуються і ніколи не говорить нічого про упорядкування даних.
Kusalananda

2
Хитрість αғsnιη nlкорисна commдля нав'язування впорядкованості у файлах.
glenn jackman

Відповіді:


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=''ми вимикаємо вихід, якщо рядок відрізнявся для файлу1, який відомий як старий файл на команду 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

Пітон 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 відповідно. Файли переспрямовуються до них двома вхідними перенаправленнями до циклу.


0
Tried with awk command and it worked fine


awk 'NR==FNR{a[$1];next}{if ($1 in a){print "TRUE"} else{print "False"}}' file1 file2

вихід

TRUE
TRUE
False
False
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.