Если вы можете использовать GNU awk (, который обычно доступен в любом стандартном дистрибутиве Linux ), вы можете использовать выражения sub -с функцией gensub()
:
< input_data awk -- '{gsub("\\|", ","); print gensub("([[:alpha:]][^=]*)=([^,]+)", "\"\\1\"=\"\\2\"", "g")}'
Предположим, что |
появляется только как разделитель пар ключей -и значений -, первый gsub()
преобразует каждый |
в ,
, а затем функция gensub()
делает все остальное.
Если вы должны использовать POSIX awk, вы все равно можете получить то же самое с помощью одного скрипта, используя последовательность (действительно неудобно..)gsub()
s:
< input_data awk -- '{gsub("=", "\""); gsub("([[:alpha:]][^\"]*)", "\"&\"="); gsub("\"[^|]*", "&\""); gsub("\\|", ","); print;}'
Разобрано (только awk
часть скрипта):
{
gsub("=", "\"");
gsub("([[:alpha:]][^\"]*)", "\"&\"=");
gsub("\"[^|]*", "&\"");
gsub("\\|", ",");
print;
}
Первый gsub()
заменяет каждый =
на "
, прокладывая путь для последующей пары gsub()
с, первый ищет ключи до (, но исключает )первый "
и заменив всю эту строку начальным "
плюс найденный ключ плюс конечный "=
, а второй gsub()
ищет значения, начинающиеся с "
(, которые первоначально были=
)до (. ] но исключая )первый|
(если он присутствует )и заменяя эту строку самой собой плюс конечный "
.
В основном это второе решение использует "
в качестве вспомогательного ключа -разделителя значений,поэтому требует, чтобы он не появлялся ни в ключах, ни в значениях.
Окончательное решение gsub()
заменяет все |
в ,
так же, как и в первом решении.