Как анализировать данные CSV в Bash

Опубликовано: 2022-09-16
Джейн Келли/Shutterstock.com

Файлы со значениями, разделенными запятыми (CSV), являются одним из наиболее распространенных форматов для экспортируемых данных. В Linux мы можем читать файлы CSV с помощью команд Bash. Но это может стать очень сложным, очень быстро. Мы протянем руку помощи.

Что такое CSV-файл?

Файл значений, разделенных запятыми, представляет собой текстовый файл, содержащий табличные данные. CSV — это тип данных с разделителями. Как следует из названия, запятая « , » используется для отделения каждого поля данных — или значения — от его соседей.

Что такое CSV-файл и как его открыть?
СВЯЗАННЫЕ Что такое файл CSV и как его открыть?

CSV везде. Если приложение имеет функции импорта и экспорта, оно почти всегда будет поддерживать CSV. Файлы CSV удобочитаемы. Вы можете заглянуть внутрь них с меньшими затратами, открыть их в любом текстовом редакторе и переместить из программы в программу. Например, вы можете экспортировать данные из базы данных SQLite и открыть их в LibreOffice Calc.

Однако даже CSV может стать сложным. Хотите иметь запятую в поле данных? Это поле должно быть заключено в кавычки " " ". Чтобы включить кавычки в поле, необходимо ввести каждую кавычку дважды.

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

Некоторые примеры данных

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

Мы создали файл, содержащий 50 строк фиктивной информации о сотрудниках:

  • id : Простое уникальное целочисленное значение.
  • firstname : Имя человека.
  • lastname : Фамилия человека.
  • job-title : Должность человека.
  • адрес электронной почты : адрес электронной почты человека.
  • branch : Филиал компании, в котором они работают.
  • state : состояние, в котором находится ветка.

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

Образец CSV-файла

Первая строка содержит имена полей в виде значений, разделенных запятыми.

Разбор данных из файла CSV

Давайте напишем скрипт, который будет читать файл CSV и извлекать поля из каждой записи. Скопируйте этот сценарий в редактор и сохраните его в файл с именем «field.sh».

 #! /бин/баш

в то время как IFS="," read -r id имя фамилия должность электронная почта филиал состояние
делать
  echo "Идентификатор записи: $id"
  эхо "Имя: $firstname"
  эхо "Фамилия: $lastname"
  echo "Название должности: $jobtitle"
  echo "Добавить адрес электронной почты: $email"
  эхо "Ветка: $ветка"
  эхо "Состояние: $state"
  эхо ""
сделано < <(хвост -n +2 образец.csv)

В нашем маленьком сценарии довольно много всего. Давайте сломаем это.

Как обрабатывать файл построчно в скрипте Linux Bash
СВЯЗАННЫЕ С : Как обрабатывать файл построчно в сценарии Linux Bash

Мы используем цикл while . Пока условие цикла while принимает значение true, будет выполняться тело цикла while . Тело цикла довольно простое. Набор операторов echo используется для вывода значений некоторых переменных в окно терминала.

Условие цикла while более интересно, чем тело цикла. Мы указываем, что запятая должна использоваться в качестве внутреннего разделителя полей, с оператором IFS="," . IFS — это переменная среды. Команда read обращается к своему значению при разборе последовательности текста.

Мы используем параметр -r (сохранять обратную косую черту) команды read , чтобы игнорировать любые обратные косые черты, которые могут быть в данных. Они будут рассматриваться как обычные персонажи.

Текст, анализируемый командой read , хранится в наборе переменных, названных в соответствии с полями CSV. С таким же успехом их можно было бы назвать field1, field2, ... field7 , но осмысленные имена облегчают жизнь.

Данные получаются на выходе команды tail . Мы используем tail , потому что это дает нам простой способ пропустить строку заголовка CSV-файла. Опция -n +2 (номер строки) указывает tail начать чтение со второй строки.

Конструкция <(...) называется подстановкой процесса. Это заставляет Bash принимать выходные данные процесса, как если бы они исходили из файлового дескриптора. Затем он перенаправляется в цикл while , предоставляя текст, который будет анализировать команда read .

Сделайте скрипт исполняемым с помощью команды chmod . Вам нужно будет делать это каждый раз, когда вы копируете сценарий из этой статьи. Подставьте имя соответствующего скрипта в каждом случае.

 chmod +x field.sh 

Делаем скрипт исполняемым с помощью chmod

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

 ./поле.ш 

Файл CSV, проанализированный скриптом field.sh.

Каждая запись печатается как набор полей.

Выбор полей

Возможно, мы не хотим или не должны извлекать каждое поле. Мы можем получить набор полей, включив команду cut .

Этот скрипт называется «select.sh».

 #!/бин/баш

в то время как IFS="," read -r id состояние ветки jobtitle
делать
  echo "Идентификатор записи: $id"
  echo "Название должности: $jobtitle"
  эхо "Ветка: $ветка"
  эхо "Состояние: $state"
  эхо ""
сделано < <(cut -d "," -f1,4,6,7 sample.csv | хвост -n +2)

Мы добавили команду cut в предложение замены процесса. Мы используем параметр -d (разделитель), чтобы указать cut использовать запятые « , » в качестве разделителя. Параметр -f (поле) сообщает cut , что нам нужны поля один, четыре, шесть и семь. Эти четыре поля считываются в четыре переменные, которые печатаются в теле цикла while .

Вот что мы получаем, когда запускаем скрипт.

 ./выбрать.ш 

Анализ файла CSV с помощью field.sh для извлечения определенного набора полей

Добавив команду cut , мы можем выбирать нужные поля и игнорировать те, которые нам не нужны.

Все идет нормально. Но…

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

 идентификатор, имя, фамилия, должность, адрес электронной почты, филиал, штат
1, Розалин, Бреннан, "Стюард, старший", [email protected], Миннеаполис, Мэриленд
2, Дэнни, Редден, «Аналитик «Бюджет»», [email protected], Венеция, Северная Каролина
3, Лекси, Роско, фармацевт, Ирлингтон, Вермонт
  • Первая запись содержит запятую в поле job-title , поэтому это поле необходимо заключить в кавычки.
  • Во второй записи есть слово, заключенное в два набора кавычек в поле jobs-title .
  • Запись три не содержит данных в поле email-address .

Эти данные были сохранены как «sample2.csv». Измените свой сценарий «field.sh», чтобы он вызывал «sample2.csv», и сохраните его как «field2.sh».

 #! /бин/баш

в то время как IFS="," read -r id имя фамилия должность электронная почта филиал состояние
делать
  echo "Идентификатор записи: $id"
  эхо "Имя: $firstname"
  эхо "Фамилия: $lastname"
  echo "Название должности: $jobtitle"
  echo "Добавить адрес электронной почты: $email"
  эхо "Ветка: $ветка"
  эхо "Состояние: $state"
  эхо ""
сделано < <(хвост -n +2 sample2.csv)

Когда мы запускаем этот скрипт, мы видим появление трещин в наших простых парсерах CSV.

 ./поле2.ш 

Запуск field2.sh

Первая запись разбивает поле «название должности» на два поля, а вторая часть обрабатывается как адрес электронной почты. Каждое поле после этого сдвигается на одну позицию вправо. Последнее поле содержит значения как branch , так и state .

Запись с полем, разделенным на два поля

Вторая запись сохраняет все кавычки. Слово «Бюджет» должно быть заключено только в одну пару кавычек.

Запись с неправильно обработанными кавычками

Третья запись фактически обрабатывает отсутствующее поле, как и должно быть. Адрес электронной почты отсутствует, но все остальное в порядке.

Запись с отсутствующим полем, которая обрабатывается правильно

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

Как использовать команду awk в Linux
СВЯЗАННЫЕ Как использовать команду awk в Linux

Попытка написать безошибочный синтаксический анализатор CSV, вероятно, не лучший путь вперед. Альтернативный подход — особенно если вы работаете в какой-то срок — использует две разные стратегии.

Один из них — использовать специально разработанный инструмент для обработки и извлечения ваших данных. Второй — очистить ваши данные и заменить проблемные сценарии, такие как встроенные запятые и кавычки. Тогда ваши простые парсеры Bash смогут справиться с удобным для Bash CSV.

Инструментарий csvkit

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

Чтобы установить его в Ubuntu, используйте эту команду:

 sudo apt установить csvkit 

Установка csvkit на Ubuntu

Чтобы установить его в Fedora, вам нужно ввести:

 sudo dnf установить python3-csvkit 

Установка csvkit в Fedora

На Manjaro команда:

 sudo pacman -S csvkit 

Установка csvkit на Manjaro

Если мы передаем ему имя CSV-файла, утилита csvlook отображает таблицу, показывающую содержимое каждого поля. Содержимое поля отображается, чтобы показать, что представляет собой содержимое поля, а не так, как оно хранится в файле CSV.

Давайте попробуем csvlook с нашим проблемным файлом «sample2.csv».

 csvlook образец2.csv 

проблемный CSV правильно анализируется csvlook

Все поля отображаются корректно. Это доказывает, что проблема не в CSV. Проблема в том, что наши скрипты слишком упрощены, чтобы правильно интерпретировать CSV.

Чтобы выбрать определенные столбцы, используйте команду csvcut . -c (столбец) можно использовать с именами полей или номерами столбцов, или с тем и другим вместе.

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

Все эти три команды эквивалентны.

 csvcut -c фамилия, имя, должность, адрес электронной почты sample2.csv
 csvcut -c фамилия, имя, 4,5 sample2.csv
 csvcut -c 3,2,4,5 пример2.csv 

Выбор полей в предпочтительном порядке с помощью csvcut

Мы можем добавить команду csvsort для сортировки вывода по полю. Мы используем параметр -c (столбец), чтобы указать столбец для сортировки, и параметр -r (обратный), чтобы сортировать в порядке убывания.

 csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r 

Выбор полей и их сортировка по одному столбцу

Чтобы сделать вывод более красивым, мы можем передать его через csvlook .

 csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r | csvlook 

Использование csvlook для красивой печати отсортированного выбора полей

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

Мы добавили больше данных в файл «sample2.file», удалили команду csvsort и создали новый файл с именем «sample3.csv».

 csvcut -c 3,2,4,5 образец2.csv > образец3.csv 

Безопасный способ очистки данных CSV

Если вы откроете файл CSV в LibreOffice Calc, каждое поле будет помещено в ячейку. Вы можете использовать функцию поиска и замены для поиска запятых. Вы можете заменить их на «ничего», чтобы они исчезли, или на символ, который не повлияет на синтаксический анализ CSV, например точку с запятой « ; " Например.

Вы не увидите кавычек вокруг полей в кавычках. Единственные кавычки, которые вы увидите, — это встроенные кавычки внутри данных поля. Они отображаются в виде одинарных кавычек. Поиск и замена их одним апострофом « ' » заменит двойные кавычки в файле CSV.

Использование поиска и замены LibreOffice Calc для замены кавычек апострофами

Выполнение поиска и замены в таком приложении, как LibreOffice Calc, означает, что вы не можете случайно удалить запятые-разделители полей или удалить кавычки вокруг полей в кавычках. Вы только измените значения данных полей.

Мы заменили все запятые в полях точками с запятой и все встроенные кавычки на апострофы и сохранили наши изменения.

Измененный файл CSV

Затем мы создали скрипт под названием «field3.sh» для анализа «sample3.csv».

 #! /бин/баш

в то время как IFS = "," читать -r фамилия имя должность электронная почта
делать
  эхо "Фамилия: $lastname"
  эхо "Имя: $firstname"
  echo "Название должности: $jobtitle"
  echo "Добавить адрес электронной почты: $email"
  эхо ""
сделано < <(tail -n +2 sample3.csv)

Посмотрим, что мы получим, когда запустим его.

 ./поле3.ш 

Раздел правильно проанализированного CSV

Наш простой синтаксический анализатор теперь может обрабатывать ранее проблемные записи.

Вы увидите много CSV

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

СВЯЗАННЫЕ С: 9 примеров сценариев Bash, которые помогут вам начать работу в Linux