我的输入文件包含以下格式的数据:
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
我必须转换第二列,其中每对都key=value
应该用双引号引起来,"key"="value"
并且应该使用以下内容|
替换为。,
awk
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"
答案1
$ sed -e 's/|/","/g' -e 's/=/"="/g' -e 's/\t/\t"/' -e 's/$/"/' input.txt
这会:
- 将任何替换
|
为,
- 将任何替换
=
为"="
- 将第一个制表位替换为
\t"
- 追加 a
"
和行尾
最简单的方法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
答案2
使用 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"
答案3
如果您可以使用 GNU awk(通常在任何标准 Linux 发行版上都可用),则可以将子表达式与函数一起使用gensub()
:
< input_data awk -- '{gsub("\\|", ","); print gensub("([[:alpha:]][^=]*)=([^,]+)", "\"\\1\"=\"\\2\"", "g")}'
假设|
仅作为键值对分隔符出现,则首先gsub()
将每个值转换为|
in ,
,然后该gensub()
函数执行其余的操作。
如果您必须使用 POSIX awk,那么您仍然可以使用一系列(确实很尴尬......)的单个脚本获得相同的结果gsub()
:
< input_data awk -- '{gsub("=", "\""); gsub("([[:alpha:]][^\"]*)", "\"&\"="); gsub("\"[^|]*", "&\""); gsub("\\|", ","); print;}'
分解(仅awk
脚本部分):
{
gsub("=", "\"");
gsub("([[:alpha:]][^\"]*)", "\"&\"=");
gsub("\"[^|]*", "&\"");
gsub("\\|", ",");
print;
}
第一个gsub()
将每个替换=
为 a "
,为随后的几个gsub()
s 铺平道路,第一个查找键直到(但不包括)第一个"
,并将整个字符串替换为前导"
加上找到的键加上尾随"=
,第二个gsub()
查找以"
(最初是=
)开始直到(但不包括)第一个|
(如果存在)的值,并将该字符串替换为其自身加上尾随的"
。
基本上,第二个解决方案用作"
辅助键值分隔符,因此要求它不会出现在键或值中。
最终解决方案gsub()
将全部替换|
为,
第一个解决方案。
答案4
通过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"