Я столкнулся с этой проблемой, используя Docker и Centos 7. В итоге я сделал следующее:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
Я нашел этот хак на https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile
$ sed -e 's/|/","/g' -e 's/=/"="/g' -e 's/\t/\t"/' -e 's/$/"/' input.txt
Это будет:
|
на,
=
на"="
\t"
"
и конец строки Самый простой способ с awk
— перейти на разделители полей:
$ awk -v FS="|" -v OFS='","' '{$1=$1}1' \
| awk -v FS="=" -v OFS='"="' '{$1=$1}1'\
| awk -v FS="\t" '{print $1,"\""$2"\""}' input.txt
Использование sed:
sed -e 's/|/","/g;s/=/"="/g;s/ /"/4;s/$/"/g' file
1503668542862176 "manager"="10001","Bounced"="999","Analyst"="10004","Business Analyst"="10005","Programmer"="10003"
1552024948590636 "manager"="10001","Bounced"="999","Analyst"="10004"
1551728916565460 "Bounced"="999","Analyst"="10004"
1553617087089790 "Analyst"="10004"
1538058487418963 "manager"="10001","Architect"="10002","Analyst"="10004"
Если вы можете использовать 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()
заменяет все |
в ,
так же, как и в первом решении.
Вы можете сделать это с помощью гладкого регулярного выражения, или вы можете сделать это, проанализировав поля, разбив их по соответствующим разделителям и реконструировав их так, как вы хотите, используяawk
:
BEGIN {
# Assume the two fields are tab-delimited.
OFS = FS = "\t"
}
NF > 1 {
# Split the 2nd field into sub-fields on "|" in the array a.
n = split($2, a, "|")
for (i = 1; i <= n; ++i)
# Split each sub-field on "=" and quote the two bits,
# and put them together again.
if (split(a[i], b, "=") == 2)
a[i] = sprintf("\"%s\"=\"%s\"", b[1], b[2])
else {
# Bail out on bad fields.
print >"/dev/stderr"
printf("Error in field %d on line %d\n", i, FNR) >"/dev/stderr"
exit 1
}
# Reconstruct current record.
$0 = $1
$2 = a[1]
for (i = 2; i <= n; ++i)
$2 = $2 "," a[i]
# Done, output
print
}
Тестирование:
$ awk -f script.awk file
1503668542862176 "manager"="10001","Bounced"="999","Analyst"="10004","Business Analyst"="10005","Programmer"="10003"
1552024948590636 "manager"="10001","Bounced"="999","Analyst"="10004"
1551728916565460 "Bounced"="999","Analyst"="10004"
1553617087089790 "Analyst"="10004"
1538058487418963 "manager"="10001","Architect"="10002","Analyst"="10004"
Выполнено командой awk
команда:
awk '{gsub(/\|/,",",$0);print $0}' filename | awk '{$2="\""$2;print $0}'| awk '{gsub(/\=/,"\"=\"",$0);print $0}'| awk '{gsub(/\,/,"\",\"",$0);print $0}'| awk '{$NF=$NF"\"";print $0}'
выход
awk '{gsub(/\|/,",",$0);print $0}' filename| awk '{$2="\""$2;print $0}'| awk '{gsub(/\=/,"\"=\"",$0);print $0}'| awk '{gsub(/\,/,"\",\"",$0);print $0}'| awk '{$NF=$NF"\"";print $0}'
1503668542862176 "manager"="10001","Bounced"="999","Analyst"="10004","Business Analyst"="10005","Programmer"="10003"
1552024948590636 "manager"="10001","Bounced"="999","Analyst"="10004"
1551728916565460 "Bounced"="999","Analyst"="10004"
1553617087089790 "Analyst"="10004"
1538058487418963 "manager"="10001","Architect"="10002","Analyst"="10004"