$ perl -MText::CSV_XS=csv -wE'csv(in=>csv(in=>"test.csv",sep=>";",allow_loose_quotes=>1,allow_loose_escapes=>1),always_quote=>1)'
",0000000000000000","0","1115S021121-12-1/2""M"
",0000000000000000","0","1115S021122-12-1/2""M"
",0000000000000000","0","1115S021123-12-1/2""M"
",0000000000000000","0","1115S021124-12-1/2""M"
"1","1","EXAMPLE_RANDOM"" . STRING"
"2,0000000000000000","2","this;can""also happen"
Как заметил Чороба, с ";"в качестве выходного sep тоже:
$ perl -MText::CSV_XS=csv -wE'csv(in=>csv(in=>"test.csv",sep=>";",allow_loose_quotes=>1,allow_loose_escapes=>1),always_quote=>1,sep=>";")'
",0000000000000000";"0";"1115S021121-12-1/2""M"
",0000000000000000";"0";"1115S021122-12-1/2""M"
",0000000000000000";"0";"1115S021123-12-1/2""M"
",0000000000000000";"0";"1115S021124-12-1/2""M"
"1";"1";"EXAMPLE_RANDOM"" . STRING"
"2,0000000000000000";"2";"this;can""also happen"
Объяснение добавлено по запросу:
Text :: CSV_XS - это модуль perl, который может анализировать и генерировать CSV очень гибким способом.Использование параметров / атрибутов для разрешения плохо отформатированного CSV.
csv (in => "file.csv", ...) считывает файл во внутреннюю структуру
sep => ";"устанавливает символ разделителя на ";"вместо значения по умолчанию ","
allow_loose_quotes => 1 и allow_loose_escapes => 1 позволяют прочитать неправильный CSV и принять неэкранированные вложенные кавычки
csv () возвращает ссылку на внутреннюю структуру, которая действительна для внешнего вызова csv, который генерирует выходной файл csv (in => csv (in => "file.csv")
Последние два аргумента устанавливают для sep также значение ";" и выводят все поля в кавычки, поскольку требуется OP
См. https://metacpan.org/module/Text::CSV_XSдля всех опций и примеров
Отформатированный в скрипте, он может выглядеть как
use Text::CSV_XS qw( csv );
csv ( # Outer function
always_quote => 1, # Quote all field
sep => ";", # Use ; instead of ,
in => # Input
csv ( # comes from inner function
in => "test.csv", # a file
sep => ";", # ; instead of ,
allow_loose_quotes => 1, # allow ,"foo"bar",
allow_loose_escapes => 1, # idem
)
);