Преобразование CSV-файла с помощью sed

для того чтобы иметь возможность импортировать данные в определенный инструмент, я должен преобразовать CSV-файл из этого формата

"data","data","data data","data","123"

в формате

data;data;data data;data;123

столбцы никогда не содержат ",; или , но могут быть пробелы. В настоящее время я использую следующие

sed -e 's/","/;/g' -e 's/"//g' input.csv > output.csv

хотя это прекрасно работает, интересно, можно ли это сделать более элегантно, т. е.

  • является ли sed правильным (стандартным Unix) инструментом для работу?
  • можно ли объединить два выражения в одно?

Спасибо за Ваш вклад!

1
задан middus
12.12.2022 7:58 Количество просмотров материала 2606
Распечатать страницу

3 ответа

( tr , ';' | tr -d '"' ) < input.csv > output.csv

Я бы использовал Perl

perl -pe 'tr/,"/;/d' input.csv > output.csv

-- но эта конкретная задача не выходит за рамки sed. Невозможно объединить два выражения.

6
отвечен ayrnieu 2022-12-13 15:46

что вы предпочитаете (perl, sed, awk) до вас; они все получат работу сделанный. Так как вы попросили sed, а остальные отправлены, вот. Это простая форма ваших регулярных выражений и работы с Пример:

$ sed -e 's/"//g; s/,/;/g' infile.csv > outfile.csv

Примечание can соединить два выражения точкой с запятой после каждой подстановки. Протестировано с GNU sed v4.1.5.

вот ваши оригинальные выражения присоединились:

$ sed -e 's/","/;/g; s/"//g' infile.csv > outfile.csv

Я вполне уверен, что это возможно объединить две замены. Не уверен, что это будет навскидку, и я уверен, что результат будет гораздо менее читаемым, чем сценарий наверху. Если я придумаю что-то (или кто-то еще весит в комментариях), я добавлю его здесь.

5
отвечен quack quixote 2022-12-13 18:03

так как вы имеете дело с записями,awk больше смысла. Тем не менее, это не очень хорошо в CSV, так как разделители полей несколько переменны. Но если вы уверены, что все поля окружены двойными порядками, это сработает:

awk -F'","' 'BEGIN {OFS=";"} { gsub(/(^")|("$)/, ""); =; print }'

устанавливает разделитель полей ввода awk в"","" (включая внутренний набор прямые кавычки). Это почти работает, за исключением вам придется иметь дело с начальные и конечные прямые кавычки, которые содрали с gsub функция. The = заставляет перекомпилировать запись с новым разделителем выходного поля, который был определен как ; в блоке BEGIN. Тогда print выводит всю запись.

это немного аккуратнее:

awk -F '(^")|(",")|("$)' 'BEGIN {OFS=";"} { =; print }'

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

awk -F '(^")|(",")|("$)' 'BEGIN {OFS=";"} { NF=NF-1; =; print }'

NF - количество полей и уменьшение его на один отрезок от последнего поля. Но я не могу придумать способ отрезать первое поле.

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

awk -F '(^")|(",")|("$)' 'BEGIN {OFS=";"} { print ,,,, }'

обратите внимание, это избавляется от = construct, который нам нужен только в том случае, если мы печатаем (подразумеваемый) $0.

все, что сказал, Я, вероятно, в конечном итоге с помощью perl и один из многих доступно CSV модули на CPAN.

4
отвечен wfaulk 2022-12-13 20:20

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх