Вопрос или проблема
У меня есть файл 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.