Как заменить N-ый разделитель в файле csv?

Вопрос или проблема

У меня есть файл csv, разделенный запятыми, например:

1,92345,92345,Уважаемый пользователь, это ваша сумма , 2016-10-10 
2,92345,92345,Уважаемый пользователь, это ваша сумма , 2016-10-09

Мне нужно заменить 4-ю запятую , только после Уважаемый пользователь на вертикальную черту |.

Используя sed, вы можете конкретно указать sed, какие вхождения шаблона вы хотите заменить, таким образом:

sed 's/,/|/4' infile

Или другое решение будет таким:

sed -r 's/^([^,]*,)([^,]*,)([^,]*,)([^,]*),(.*)/\1\2\3\4|\5/' infile

Обрабатывая ввод в формате CSV без заголовка, который может содержать встроенные запятые и т. д., и обрабатывая его с помощью Miller (mlr), инструмента, понимающего CSV, сначала удаляя боковые пробелы из каждого поля, а затем перемещая данные из 5-го поля в 4-е поле с разделителем в виде вертикальной черты. В конце 5-е поле удаляется.

$ cat file
1,92345,92345,Уважаемый пользователь, это ваша сумма , 2016-10-10
2,92345,92345,Уважаемый пользователь, это ваша сумма , 2016-10-09
3,99999,99999,"Это поле содержит встроенную запятую ,","а это поле содержит ""кавычку""",2025-03-03
$ mlr --csv -N clean-whitespace then put '$4 .= "|" . $5' then cut -x -f 5 file
1,92345,92345,Уважаемый пользователь|это ваша сумма,2016-10-10
2,92345,92345,Уважаемый пользователь|это ваша сумма,2016-10-09
3,99999,99999,"Это поле содержит встроенную запятую ,|а это поле содержит ""кавычку""",2025-03-03

Ответ или решение

Замена определенного разделителя в CSV-файле – задача, с которой часто сталкиваются в практике обработки данных. Рассмотрим, как это можно сделать, используя инструменты командной строки, такие как sed и mlr (Miller).

Теория

CSV (Comma-Separated Values) – это формат файла, который широко используется для хранения табличных данных. Несмотря на свою простоту, обработка CSV-файлов может вызывать трудности, особенно если данные содержат вложенные запятые или иные разделители. Одной из часто встречающихся задач является замена определенного по счету разделителя в строке. В нашем случае требуется заменить четвертую запятую на символ вертикальной черты (|), сохраняя при этом целостность данных.

Пример

Чтобы лучше понять задачу, рассмотрим пример CSV-файла:

1,92345,92345,Dear user, this is your amount , 2016-10-10
2,92345,92345,Dear user, this is your amount , 2016-10-09
3,99999,99999,"This field contains an embedded ,","and this field contains ""a quote""",2025-03-03

В этом файле необходимо заменить четвертую запятую на символ вертикальной черты (|), но только после слов "Dear user".

Применение

Существуют различные способы решения этой задачи с использованием инструментов командной строки. Рассмотрим несколько из них.

Использование sed

sed – это мощный инструмент потокового редактирования, который позволяет модифицировать текстовые данные на лету. Чтобы заменить четвертую запятую с помощью sed, можно использовать следующий синтаксис:

sed 's/,/|/4' infile

Однако, этот метод заменяет четвертую запятую во всех строках, что может быть нежелательным, если в строках после "Dear user" может встречаться текст с запятыми. Более точный подход – использовать регулярные выражения:

sed -r 's/^([^,]*,)([^,]*,)([^,]*,)([^,]*),(.*)/\1\2\3\4|\5/' infile

Этот шаблон ищет и заменяет только четвертую запятую, сохраняя при этом прежнюю структуру строки. Символы \1, \2, и т.д. используются для сохранения содержимого, захваченного подвыражениями.

Использование Miller (mlr)

Miller (сокращенно mlr) – это утилита для обработки данных в формате CSV, которая учитывает наличие вложенных запятых, кавычек и других символов. Она обладает расширенными возможностями по сравнению с традиционными инструментами. Для решения нашей задачи с помощью mlr можно использовать следующую последовательность команд:

mlr --csv -N clean-whitespace then put '$4 .= "|" . $5' then cut -x -f 5 file

Здесь --csv -N сообщает Miller, что файл следует интерпретировать как CSV без заголовков. Команда clean-whitespace удаляет лишние пробелы из полей, put '$4 .= "|" . $5' добавляет к содержимому четвертого поля символ | и пятое поле, а cut -x -f 5 удаляет пятое поле, оставляя файл в нужной конфигурации.

Заключение

Таким образом, задача замены N-го разделителя в CSV-файле может быть решена различными методами в зависимости от контекста использования и требуемой точности. sed предоставляет базовые возможности для прямой замены, в то время как mlr предлагает более сложный функционал для обработки данных, содержащих вложенные запятые и кавычки. Оба этих инструмента являются мощными средствами в арсенале специалиста по обработке данных и могут быть использованы в зависимости от конкретных требований к задаче. Надеюсь, данное объяснение и примеры применения помогут в эффективной работе с файлами CSV.

Оцените материал
Добавить комментарий

Капча загружается...