Як використовувати команду приєднання в Linux

Якщо вам потрібно поєднати інформацію з двох текстових файлів, використовуючи спільне поле для зіставлення, команда `join` в Linux стане вам у пригоді. Вона надає можливість динамічно обробляти статичні файли з даними. Давайте розглянемо, як її використовувати.

Зіставлення даних з різних файлів

Інформація є надзвичайно цінною для всіх: корпорацій, малих підприємств та навіть окремих користувачів. Проте, дані, що зберігаються в різних файлах і збираються різними людьми, часто створюють проблеми. Не тільки потрібно знати, які файли відкривати для пошуку потрібної інформації, а й макети та формати цих файлів можуть істотно відрізнятися.

Також виникають адміністративні труднощі, пов’язані з визначенням файлів, які потрібно оновити, резервувати, які є застарілими, а які можна архівувати.

Крім того, якщо потрібно об’єднати всі дані або провести аналіз усього набору, виникає додаткова складність. Як упорядкувати інформацію з різних файлів, перш ніж використовувати її? Який підхід застосувати на етапі підготовки даних?

На щастя, якщо файли мають хоча б один спільний елемент даних, команда `join` в Linux допоможе вам подолати ці труднощі.

Файли з даними

Всі дані, які ми будемо використовувати для демонстрації команди `join`, є вигаданими. Розглянемо спочатку вміст двох наступних файлів:

cat file-1.txt
cat file-2.txt

Ось вміст файлу `file-1.txt`:

1 Adore Varian [email protected] Female 192.57.150.231
2 Nancee Merrell [email protected] Female 22.198.121.181
3 Herta Friett [email protected] Female 33.167.32.89
4 Torie Venmore [email protected] Female 251.9.204.115
5 Deni Sealeaf [email protected] Female 210.53.81.212
6 Fidel Bezley [email protected] Male 72.173.218.75
7 Ulrikaumeko Standen [email protected] Female 4.204.0.237
8 Odell Jursch [email protected] Male 1.138.85.117

Кожен рядок містить таку інформацію:

Номер
Ім’я
Прізвище
Електронна адреса
Стать
IP-адреса

А ось вміст файлу `file-2.txt`:

1 Varian [email protected] Female Western New York $535,304.73
2 Merrell [email protected] Female Finger Lakes $309,033.10
3 Friett [email protected] Female Southern Tier $461,664.44
4 Venmore [email protected] Female Central New York $175,818.02
5 Sealeaf [email protected] Female North Country $126,690.15
6 Bezley [email protected] Male Mohawk Valley $366,733.78
7 Standen [email protected] Female Capital District $674,634.93
8 Jursch [email protected] Male Hudson Valley $663,821.09

У файлі `file-2.txt` кожен рядок містить такі дані:

Номер
Прізвище
Електронна адреса
Стать
Регіон Нью-Йорка
Сума в доларах

Команда `join` оперує “полями”, під якими розуміється фрагмент тексту, обмежений пробілами, початком або кінцем рядка. Для того, щоб об’єднання рядків з двох файлів було успішним, кожен рядок має містити спільне поле.

Отже, зіставити поле можна лише тоді, коли воно присутнє в обох файлах. IP-адреса є тільки в одному файлі, тому не підходить. Ім’я також є лише в одному файлі, тому його не можна використовувати. Прізвище є в обох файлах, але це не найкращий варіант, оскільки різні люди можуть мати однакове прізвище.

З’єднувати дані за ознаками “чоловіча” чи “жіноча” стать також не варіант, оскільки це занадто загальна ознака. Регіони Нью-Йорка та сума в доларах також наявні лише в одному файлі.

Проте, ми можемо використовувати електронну адресу, оскільки вона присутня в обох файлах і є унікальною для кожної особи. Швидкий перегляд файлів також підтверджує, що рядки в кожному з них відповідають одній і тій же людині, тому ми можемо використовувати номери рядків як наше поле для зіставлення (згодом ми використаємо інше поле).

Варто відзначити, що кількість полів в обох файлах відрізняється, і це нормально – ми можемо вказати `join`, яке поле використовувати з кожного файлу.

Однак, потрібно бути обережним з такими полями як регіони Нью-Йорка; в файлі, де роздільником є пробіл, кожне слово в назві регіону буде вважатися окремим полем. Оскільки деякі назви регіонів складаються з двох або трьох слів, ви отримаєте змінну кількість полів в одному файлі. Це не є проблемою, якщо ви зіставляєте поля, що розташовані в рядку перед назвами регіонів Нью-Йорка.

Використання команди `join`

Перш за все, поле, за яким ви збираєтеся проводити зіставлення, має бути відсортовано. В нашому випадку, в обох файлах є зростаючі числа, що відповідає цій вимозі. За замовчуванням, команда `join` використовує перше поле у файлі, що нам і потрібно. Іншим стандартним параметром є використання пробілів як роздільників полів. Це також відповідає нашим даним, тому ми можемо розпочинати об’єднання.

Оскільки ми використовуємо всі стандартні значення, наша команда буде виглядати просто:

join file-1.txt file-2.txt

Команда `join` розглядає файли як “перший файл” і “другий файл”, відповідно до їх порядку в командному рядку.

Вихід буде мати наступний вигляд:

1 Adore Varian [email protected] Female 192.57.150.231 Varian [email protected] Female Western New York $535,304.73
2 Nancee Merrell [email protected] Female 22.198.121.181 Merrell [email protected] Female Finger Lakes $309,033.10
3 Herta Friett [email protected] Female 33.167.32.89 Friett [email protected] Female Southern Tier $461,664.44
4 Torie Venmore [email protected] Female 251.9.204.115 Venmore [email protected] Female Central New York $175,818.02
5 Deni Sealeaf [email protected] Female 210.53.81.212 Sealeaf [email protected] Female North Country $126,690.15
6 Fidel Bezley [email protected] Male 72.173.218.75 Bezley [email protected] Male Mohawk Valley $366,733.78
7 Ulrikaumeko Standen [email protected] Female 4.204.0.237 Standen [email protected] Female Capital District $674,634.93
8 Odell Jursch [email protected] Male 1.138.85.117 Jursch [email protected] Male Hudson Valley $663,821.09

Вихід форматується так: спочатку виводиться поле, за яким було проведено зіставлення, потім інші поля з першого файлу, а потім поля з другого файлу без поля зіставлення.

Поля не відсортовані

Давайте спробуємо зробити щось, що точно не спрацює. Ми змінимо порядок рядків в одному з файлів, щоб команда `join` не могла його правильно обробити. Вміст файлу `file-3.txt` є таким самим, як і `file-2.txt`, за виключенням того, що восьмий рядок знаходиться між п’ятим і шостим рядками.

Ось вміст файлу `file-3.txt`:

1 Varian [email protected] Female Western New York $535,304.73
2 Merrell [email protected] Female Finger Lakes $309,033.10
3 Friett [email protected] Female Southern Tier $461,664.44
4 Venmore [email protected] Female Central New York $175,818.02
5 Sealeaf [email protected] Female North Country $126,690.15
8 Jursch [email protected] Male Hudson Valley $663,821.09
6 Bezley [email protected] Male Mohawk Valley $366,733.78
7 Standen [email protected] Female Capital District $674,634.93

Введемо наступну команду, щоб спробувати з’єднати `file-3.txt` з `file-1.txt`:

join file-1.txt file-3.txt

Команда `join` повідомляє, що сьомий рядок у `file-3.txt` не оброблено, оскільки він не відповідає порядку сортування. Сьомий рядок – це той, що починається з цифри шість, який має йти перед вісімкою у відсортованому списку. Шостий рядок у файлі (що починається з “8 Odell”) був останнім обробленим, тому ми бачимо його вихідні дані.

Можна скористатися опцією `–check-order`, якщо ви хочете перевірити, чи відповідають файли вимогам сортування, без спроб об’єднання.

Для цього введіть наступне:

join --check-order file-1.txt file-3.txt

`join` наперед повідомляє, що виникне проблема з сьомим рядком файлу `file-3.txt`.

Файли з відсутніми рядками

У файлі `file-4.txt` видалено останній рядок, тобто восьмий рядок відсутній. Ось його вміст:

1 Varian [email protected] Female Western New York $535,304.73
2 Merrell [email protected] Female Finger Lakes $309,033.10
3 Friett [email protected] Female Southern Tier $461,664.44
4 Venmore [email protected] Female Central New York $175,818.02
5 Sealeaf [email protected] Female North Country $126,690.15
6 Bezley [email protected] Male Mohawk Valley $366,733.78
7 Standen [email protected] Female Capital District $674,634.93

Ми вводимо наступне, і, на диво, `join` не скаржиться і обробляє всі рядки, які може:

join file-1.txt file-4.txt

Вихідні дані містять сім об’єднаних рядків.

Параметр `-a` (вивести непарні) вказує команді `join` також виводити рядки, які не вдалося зіставити.

Тут ми вводимо наступну команду, щоб сповістити `join` вивести рядки з першого файлу, що не були зіставлені з рядками у другому файлі:

join -a 1 file-1.txt file-4.txt

Сім рядків зіставлено, а восьмий рядок з першого файлу виведено без відповідності. Об’єднаної інформації немає, оскільки у `file-4.txt` не було восьмого рядка, з яким його можна було б зіставити. Але, принаймні, він все ще відображається у виводі, щоб ви знали, що він не має відповідності у файлі `file-4.txt`.

Ми вводимо наступну команду `-v` (придушити об’єднані рядки), щоб виявити будь-які рядки, які не мають збігу:

join -v file-1.txt file-4.txt

Ми бачимо, що восьмий рядок єдиний, який не має відповідності у другому файлі.

Зіставлення за іншими полями

Зіставимо два нові файли за полем, що не є першим. Ось вміст `file-7.txt`:

[email protected] Female 192.57.150.231
[email protected] Female 210.53.81.212
[email protected] Male 72.173.218.75
[email protected] Female 33.167.32.89
[email protected] Female 22.198.121.181
[email protected] Male 1.138.85.117
[email protected] Female 251.9.204.115
[email protected] Female 4.204.0.237

А ось вміст `file-8.txt`:

Female [email protected] Western New York $535,304.73
Female [email protected] North Country $126,690.15
Male [email protected] Mohawk Valley $366,733.78
Female [email protected] Southern Tier $461,664.44
Female [email protected] Finger Lakes $309,033.10
Male [email protected] Hudson Valley $663,821.09
Female [email protected] Central New York $175,818.02
Female [email protected] Capital District $674,634.93

Єдиним розумним полем для зіставлення є електронна адреса, яка є першим полем у першому файлі та другим у другому. Щоб врахувати це, ми можемо використати параметри `-1` (поле з першого файлу) та `-2` (поле з другого файлу). За ними ми вказуємо номер, що показує, яке поле в кожному файлі використовувати для зіставлення.

Введемо наступне, щоб повідомити `join` використовувати перше поле з першого файлу, а друге з другого:

join -1 1 -2 2 file-7.txt file-8.txt

Файли об’єднуються за електронною адресою, яка відображається першим полем кожного рядка у виводі.

Використання різних роздільників полів

Що робити, якщо поля у ваших файлах розділені символами, відмінними від пробілів?

Наступні два файли розділені комами, і єдиний пробіл між назвами місць, що складаються з кількох слів:

cat file-5.txt
cat file-6.txt

Ми можемо використовувати параметр `-t` (символ роздільника), щоб вказати `join`, який символ використовувати як роздільник полів. В даному випадку це кома, тому введемо наступну команду:

join -t, file-5.txt file-6.txt

Всі рядки зіставлено, а пробіли у назвах місць збережено.

Ігнорування регістру літер

Інший файл, `file-9.txt`, майже ідентичний файлу `file-8.txt`. Єдина відмінність полягає в тому, що деякі електронні адреси мають великі літери, як показано нижче:

Female [email protected] Western New York $535,304.73
Female [email protected] North Country $126,690.15
Male [email protected] Mohawk Valley $366,733.78
Female [email protected] Southern Tier $461,664.44
Female [email protected] Finger Lakes $309,033.10
Male [email protected] Hudson Valley $663,821.09
Female [email protected] Central New York $175,818.02
Female [email protected] Capital District $674,634.93

Коли ми об’єднували `file-7.txt` і `file-8.txt`, все працювало ідеально. Подивимось, що станеться з `file-7.txt` та `file-9.txt`.

Введемо наступну команду:

join -1 1 -2 2 file-7.txt file-9.txt

Ми зіставили лише шість рядків. Різниця у великих і малих літерах не дозволила об’єднати дві інші електронні адреси.

Однак, ми можемо використати параметр `-i` (ігнорувати регістр), щоб примусово ігнорувати ці відмінності та зіставляти поля, що містять однаковий текст, незалежно від регістру.

Введемо наступну команду:

join -1 1 -2 2 -i file-7.txt file-9.txt

Усі вісім рядків зіставлені та успішно з’єднані.

Підсумок

У процесі об’єднання ви маєте потужного помічника, коли стикаєтеся з незручною підготовкою даних. Можливо, вам потрібно проаналізувати дані, або, можливо, ви намагаєтеся привести їх у формат, необхідний для імпорту в іншу систему.

В будь-якому випадку, ви будете раді, що команда `join` завжди напоготові!