假设我在这种格式的文本文件中有数百万字符串:
st=expand&c=22&t=button&k=fun HTTP
这是一个字符串,我们可以将其视为具有键st
,c
,t
和k
的哈希值。文本文件中的某些字符串可能没有给定的& KEY = VALUE,因此可能如下所示:
st=expand&k=fun HTTP
如何使用sed将字符串更改为以下
expand,,,fun
也就是说,即使认为key = value不存在,我们仍然会添加一个逗号。我们可以假设我们有一个固定的密钥集[st,c,t,k]
。
我尝试的是(只是一个想法!!)
sed 's/\(st=\|c=\|t=\|k=\)\([\(^\&\|HTTP\)])\(\&\|HTTP\)/\3,/g' big_file
但显然,如果c
不存在,则不会添加逗号,因为它找不到任何逗号。任何想法如何处理这个?使用awk
也可以接受(或任何其他快速文本处理实用程序)
谢谢!
st=expand&c=22&t=button&k=fun HTTP
c=22&t=button&k=fun HTTP
st=expand&c=22&t=party&k=fun HTTP
st=expand&c=22&k=fun HTTP
st=expand HTTP
HTTP
expand,22,button,fun
,22,button,fun
expand,22,party,fun
expand,22,,fun
expand,,,
,,,
答案 0 :(得分:2)
您可以使用此sed
:
sed -E 's/(st=([^& ]*)|)(.*c=([^& ]*)|)(.*t=([^& ]*)|)(.*k=([^& ]*)|) HTTP/\2,\4,\6,\8/' file
expand,22,button,fun
,22,button,fun
expand,22,party,fun
expand,22,,fun
expand,,,
,,,
答案 1 :(得分:1)
这样的事情怎么样?它并不是非常严格,但只要您的数据遵循您在每一行描述的格式,它就会起作用。
正则表达式:
^(?:st=([^&\n]*))?&?(?:c=([^&\n]*))?&?(?:t=([^&\n]*))?&?(?:k=([^&\n]*))? HTTP$
(必须每行运行一次或启用多行和全局选项)
换人:
\1,\2,\3,\4
在此处试试:https://regex101.com/r/nE1oP7/2
编辑:如果您使用的是sed,则需要将非捕获组更改为常规组((?:)
到()
)并相应地更新后向引用(\2,\4,\6,\8
)。演示:http://ideone.com/GNRNGp
答案 2 :(得分:1)
每当输入数据中有name = value对时,它最简单,最清晰,通常最有效的方法是创建一个name-> value数组,然后按照你想要的顺序按名称打印值,例如:
$ cat tst.awk
BEGIN { FS="[&= ]"; OFS="," }
{
delete n
for (i=1;i<NF;i+=2) {
n[$i] = $(i+1)
}
print n["st"], n["c"], n["t"], n["k"]
}
$ awk -f tst.awk file
expand,22,button,fun
,22,button,fun
expand,22,party,fun
expand,22,,fun
expand,,,
,,,
答案 3 :(得分:1)
sed
尝试的另一种模式:
sed -r "s/(st=(\w+))?(&?c=(\w+))?(&t=(\w+))?(&k=(\w+))?( HTTP)/\2,\4,\6,\8/g" big_file
expand,22,button,fun
,22,button,fun
expand,22,party,fun
expand,22,,fun
expand,,,