Я хочу порівняти файл1 з файлом2 та створити файл3, який містить рядки у файлі1, яких немає у файлі2.
Я хочу порівняти файл1 з файлом2 та створити файл3, який містить рядки у файлі1, яких немає у файлі2.
Відповіді:
diff (1) - не відповідь, але comm (1) є.
NAME
comm - compare two sorted files line by line
SYNOPSIS
comm [OPTION]... FILE1 FILE2
...
-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
Так
comm -2 -3 file1 file2 > file3
Вхідні файли повинні бути відсортовані. Якщо їх немає, спочатку відсортуйте їх. Це можна зробити з тимчасовим файлом або ...
comm -2 -3 <(sort file1) <(sort file2) > file3
за умови, що ваша оболонка підтримує процес заміщення (bash does).
comm -23
Утиліта Unix diffпризначена саме для цієї мети.
$ diff -u file1 file2 > file3
Перегляньте посібник та Інтернет для параметрів, різних форматів виводу тощо.
Розглянемо це:
файл a.txt:
abcd
efgh
файл b.txt:
abcd
Ви можете знайти різницю за допомогою:
diff -a --suppress-common-lines -y a.txt b.txt
Вихід буде:
efgh
Ви можете перенаправити вихід у вихідний файл (c.txt), використовуючи:
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
Це відповість на ваше запитання:
"... який містить рядки у file1, які відсутні у file2."
-d, що зробить diffвсе можливе, щоб знайти найменшу можливу різницю. -i, -E, -w, -BІ --suppress-blank-emptyтакож може бути корисно час від часу, хоча і не завжди. Якщо ви не знаєте, що відповідає вашому випадку використання, спробуйте diff --helpспочатку (що, як правило, непогана ідея, коли ви не знаєте, що може зробити команда).
Іноді diffпотрібна утиліта, але іноді joinє більш доцільною. Файли потрібно заздалегідь відсортувати або, якщо ви використовуєте оболонку, яка підтримує процес заміщення, такі як bash, ksh або zsh, ви можете робити сортування на льоту.
join -v 1 <(sort file1) <(sort file2)
Спробуйте
sdiff file1 file2
У більшості випадків він зазвичай працює набагато краще. Ви можете сортувати файли раніше, якщо порядок рядків не важливий (наприклад, деякі текстові конфігураційні файли).
Наприклад,
sdiff -w 185 file1.cfg file2.cfg
sdiff <(sort file1) <(sort file2))
Якщо вам потрібно вирішити це за допомогою Coreutils, прийнята відповідь хороша:
comm -23 <(sort file1) <(sort file2) > file3
Ви також можете використовувати sd (stream diff), який не потребує сортування, ні заміни процесів, а підтримує нескінченні потоки, наприклад:
cat file1 | sd 'cat file2' > file3
Напевно, не настільки велика користь на цьому прикладі, але все ж врахуйте це; в деяких випадках ви не зможете використовувати commні grep -Fні, ні diff.
Ось блогпост я писав про порівнюють потоки на терміналі, який вводить SD.
Уже багато відповідей, але жоден з них не ідеальний ІМХО. Відповідь Танатоса залишає кілька зайвих символів у рядку, а відповідь Сорпігаля вимагає, щоб файли були відсортовані або попередньо відсортовані, що може не бути адекватним за будь-яких обставин.
Я думаю , що найкращий спосіб отримання ліній , які не відрізняються , і більше нічого (ніяких додаткових символів, без повторного замовлення) являє собою комбінацію diff, grepі awk(або аналогічний).
Якщо рядки не містять жодного "<", короткий один вкладиш може бути:
diff urls.txt* | grep "<" | sed 's/< //g'
але це видалить кожен екземпляр "<" (менше місця) з рядків, що не завжди нормально (наприклад, вихідний код). Найбезпечніший варіант - використовувати awk:
diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
Цей однолінійний файл відрізняє обидва файли, потім відфільтровує виведення стилю ed у diff, а потім видаляє контур "<", який додає diff. Це працює, навіть якщо рядки містять самі "<".
diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt
Я спробував майже всі відповіді в цій темі, але жодна не була повною. Після кількох стежок вище один працював на мене. різниця дасть вам різницю, але з деякими небажаними особливими властивостями. де ви фактично різницеві лінії починаються з '>'. тому наступним кроком є обв’язування ліній, починається з '>', а потім видалення таких же з sed .
<. Ви побачите це, якщо поміняти порядок вхідних файлів. Навіть якщо ви це зробили, ви хочете опустити grep, використовуючи більше sed: `diff a1 a2 | sed '/> / s ///' `Це все ще може порушувати рядки, що містять >або <в потрібній ситуації, і залишають зайві рядки, що описують номери рядків. Якщо ви хочете спробувати цей підхід найкраще було б: diff -C0 a1 a2 | sed -ne '/^[+-] /s/^..//p'.
Ви можете використовувати diffнаступне форматування виводу:
diff --old-line-format='' --unchanged-line-format='' file1 file2
--old-line-format='', вимкніть вихід для file1, якщо рядок відрізнявся порівняйте у file2.
--unchanged-line-format='', вимкнути вихід, якщо рядки були однаковими.