正则表达式具有未知数量的参数的字符串

时间:2016-04-22 16:05:47

标签: regex awk replace sed

假设我在这种格式的文本文件中有数百万字符串:

st=expand&c=22&t=button&k=fun HTTP

这是一个字符串,我们可以将其视为具有键stctk的哈希值。文本文件中的某些字符串可能没有给定的& 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,,,
,,,

4 个答案:

答案 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,,,
,,,

Sed Demo

RegEx Demo

答案 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,,,

REGEX 101 DEMO