Поиск по сайту:

Как использовать команду присоединения в Linux


Если вы хотите объединить данные из двух текстовых файлов, сопоставив общее поле, вы можете использовать команду Linux join. Это добавляет капельку динамизма к вашим статическим файлам данных. Мы покажем вам, как его использовать.

Сопоставление данных в файлах

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

Вам также приходится сталкиваться с административной головной болью, связанной с тем, какие файлы необходимо обновлять, для каких создавать резервные копии, какие являются устаревшими, а какие можно архивировать.

Кроме того, если вам нужно консолидировать данные или провести некоторый анализ всего набора данных, у вас возникнет дополнительная проблема. Как рационализировать данные в разных файлах, прежде чем вы сможете делать с ними то, что вам нужно? Как вы подходите к этапу подготовки данных?

Хорошая новость заключается в том, что если файлы имеют хотя бы один общий элемент данных, команда Linux join может вытащить вас из трясины.

Файлы данных

Все данные, которые мы будем использовать для демонстрации использования команды join, являются вымышленными, начиная со следующих двух файлов:

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

Ниже приведено содержимое file-1.txt:

1 Adore Varian avarian0@newyorker.com Female 192.57.150.231
2 Nancee Merrell nmerrell1@ted.com Female 22.198.121.181
3 Herta Friett hfriett2@dagondesign.com Female 33.167.32.89
4 Torie Venmore tvenmore3@gmpg.org Female 251.9.204.115
5 Deni Sealeaf dsealeaf4@nps.gov Female 210.53.81.212
6 Fidel Bezley fbezley5@lulu.com Male 72.173.218.75
7 Ulrikaumeko Standen ustanden6@geocities.jp Female 4.204.0.237
8 Odell Jursch ojursch7@utexas.edu Male 1.138.85.117

У нас есть набор пронумерованных строк, и каждая строка содержит всю следующую информацию:

  • Число
  • Имя
  • Фамилия
  • Адрес электронной почты
  • Пол человека
  • IP-адрес

Ниже приведено содержимое file-2.txt:

1 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
6 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Standen ustanden6@geocities.jp Female Capital District $674,634.93
8 Jursch ojursch7@utexas.edu Male Hudson Valley $663,821.09

Каждая строка в file-2.txt содержит следующую информацию:

  • Число
  • Фамилия
  • Адрес электронной почты
  • Пол человека
  • Район Нью-Йорка
  • В долларах

Команда join работает с «полями», что в данном контексте означает часть текста, окруженную пробелами, начало строки или конец строки. Чтобы join сопоставил строки между двумя файлами, каждая строка должна содержать общее поле.

Поэтому мы можем сопоставить поле только в том случае, если оно присутствует в обоих файлах. IP-адрес появляется только в одном файле, так что это нехорошо. Первое имя появляется только в одном файле, поэтому мы не можем его использовать. Фамилия есть в обоих файлах, но это был бы плохой выбор, так как у разных людей одна и та же фамилия.

Вы также не можете связать данные вместе с мужскими и женскими записями, потому что они слишком расплывчаты. Регионы Нью-Йорка и стоимость в долларах также появляются только в одном файле.

Однако мы можем использовать адрес электронной почты, потому что он присутствует в обоих файлах, и каждый из них уникален для человека. Быстрый просмотр файлов также подтверждает, что строки в каждом из них соответствуют одному и тому же человеку, поэтому мы можем использовать номера строк в качестве нашего поля для сопоставления (позже мы будем использовать другое поле).

Обратите внимание, что в двух файлах разное количество полей, и это нормально — мы можем указать join, какое поле использовать из каждого файла.

Однако следите за такими полями, как районы Нью-Йорка; в файле, разделенном пробелом, каждое слово в названии региона выглядит как поле. Поскольку имена некоторых регионов состоят из двух или трех слов, фактически у вас будет разное количество полей в одном и том же файле. Это нормально, если вы сопоставляете поля, которые появляются в строке перед регионами Нью-Йорка.

Команда присоединения

Во-первых, поле, которое вы собираетесь сопоставлять, должно быть отсортировано. У нас есть возрастающие числа в обоих файлах, так что мы соответствуем этому критерию. По умолчанию join использует первое поле в файле, что нам и нужно. Другое разумное значение по умолчанию заключается в том, что join ожидает, что разделители полей будут пробелами. Опять же, у нас это есть, так что мы можем продолжить и запустить join.

Поскольку мы используем все значения по умолчанию, наша команда проста:

join file-1.txt file-2.txt

join считает файлы «файлом один» и «файлом два» в соответствии с порядком, в котором они перечислены в командной строке.

Результат выглядит следующим образом:

1 Adore Varian avarian0@newyorker.com Female 192.57.150.231 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Nancee Merrell nmerrell1@ted.com Female 22.198.121.181 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Herta Friett hfriett2@dagondesign.com Female 33.167.32.89 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Torie Venmore tvenmore3@gmpg.org Female 251.9.204.115 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Deni Sealeaf dsealeaf4@nps.gov Female 210.53.81.212 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
6 Fidel Bezley fbezley5@lulu.com Male 72.173.218.75 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Ulrikaumeko Standen ustanden6@geocities.jp Female 4.204.0.237 Standen ustanden6@geocities.jp Female Capital District $674,634.93
8 Odell Jursch ojursch7@utexas.edu Male 1.138.85.117 Jursch ojursch7@utexas.edu Male Hudson Valley $663,821.09

Вывод форматируется следующим образом: сначала печатается поле, в котором были сопоставлены строки, затем другие поля из первого файла, а затем поля из второго файла без поля совпадения.

Несортированные поля

Давайте попробуем то, что, как мы знаем, не сработает. Мы будем располагать строки в одном файле не по порядку, поэтому join не сможет правильно обработать файл. Содержимое file-3.txt такое же, как и у file-2.txt, но восьмая строка находится между пятой и шестой строками.

Ниже приведено содержимое file-3.txt:

1 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
8 Jursch ojursch7@utexas.edu Male Hudson Valley $663,821.09
6 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Standen ustanden6@geocities.jp 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 порядок сортировки файлов — попытки слияния предприниматься не будут.

Для этого набираем следующее:

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

join заранее сообщает вам, что может возникнуть проблема с седьмой строкой файла file-3.txt.

Файлы с пропущенными строками

В file-4.txt удалена последняя строка, поэтому восьмой строки нет. Содержание следующее:

1 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
6 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Standen ustanden6@geocities.jp 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

Мы видим, что восьмая строка — единственная, не имеющая совпадений во втором файле.

Соответствие другим полям

Давайте сопоставим два новых файла с полем, которое не является значением по умолчанию (поле 1). Ниже приводится содержимое файла-7.txt:

avarian0@newyorker.com Female 192.57.150.231
dsealeaf4@nps.gov Female 210.53.81.212
fbezley5@lulu.com Male 72.173.218.75
hfriett2@dagondesign.com Female 33.167.32.89
nmerrell1@ted.com Female 22.198.121.181
ojursch7@utexas.edu Male 1.138.85.117
tvenmore3@gmpg.org Female 251.9.204.115
ustanden6@geocities.jp Female 4.204.0.237

А вот содержимое файла-8.txt:

Female avarian0@newyorker.com Western New York $535,304.73
Female dsealeaf4@nps.gov North Country $126,690.15
Male fbezley5@lulu.com Mohawk Valley $366,733.78
Female hfriett2@dagondesign.com Southern Tier $461,664.44
Female nmerrell1@ted.com Finger Lakes $309,033.10
Male ojursch7@utexas.edu Hudson Valley $663,821.09
Female tvenmore3@gmpg.org Central New York $175,818.02
Female ustanden6@geocities.jp 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 avarian0@newyorker.com Western New York $535,304.73
Female dsealeaf4@nps.gov North Country $126,690.15
Male Fbezley5@lulu.com Mohawk Valley $366,733.78
Female hfriett2@dagondesign.com Southern Tier $461,664.44
Female nmerrell1@ted.com Finger Lakes $309,033.10
Male Ojursch7@utexas.edu Hudson Valley $663,821.09
Female tvenmore3@gmpg.org Central New York $175,818.02
Female ustanden6@geocities.jp 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 игнорировать эти различия и сопоставлять поля, содержащие один и тот же текст, независимо от регистра.

Набираем следующую команду:

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

Все восемь строк сопоставляются и успешно соединяются.

Смешивать и сочетать

В join у вас есть мощный союзник, когда вы боретесь с неудобной подготовкой данных. Возможно, вам нужно проанализировать данные, или, может быть, вы пытаетесь привести их в форму, чтобы выполнить импорт в другую систему.

Независимо от ситуации, вы будете рады, что у вас есть join в вашем углу!

RELATED: Best Linux Laptops for Developers and Enthusiasts