在Unix中使用多个分隔符拆分行

在Unix中使用多个分隔符拆分行,unix,awk,sed,split,Unix,Awk,Sed,Split,我在一个文件中有下面几行 id=1234,name=abcd,age=76 id=4323,name=asdasd,age=43 除了实际文件的每一行都有更多的tag=value字段之外。 我希望最终的输出是这样的 id,name,age 1234,abcd,76 4323,asdasd,43 我希望=前面(左边)的所有值以分隔,第一行是,,每行中=后面(右边)的所有值都在下面 有没有办法用awk或sed来实现这一点?请让我知道是否同样需要for循环 我正在Solaris 10上工作;本地s

我在一个文件中有下面几行

id=1234,name=abcd,age=76
id=4323,name=asdasd,age=43
除了实际文件的每一行都有更多的
tag=value
字段之外。 我希望最终的输出是这样的

id,name,age
1234,abcd,76
4323,asdasd,43
我希望
=
前面(左边)的所有值以
分隔,第一行是
,每行中
=
后面(右边)的所有值都在下面

有没有办法用
awk
sed
来实现这一点?请让我知道是否同样需要for循环

我正在Solaris 10上工作;本地
sed
不是GNU
sed
(因此没有
-r
选项,也没有
-E

编辑:或使用

sed '1 s/^/id,name,age\n/;s/id=\|name=\|age=//g'
输出

id,name,age
1234,abcd,76 ...(n number of fields)
4323,asdasd,43...

下面简单地结合了迄今为止基于sed的最佳答案,说明你可以吃蛋糕,也可以吃蛋糕。如果您的sed不支持-r选项,那么很可能-E会起作用;如果所有其他方法都失败,则可以用RR*替换R+,其中R为[^,]

sed -r '1s/=[^,]+//g; s/[^,]+=//g'
(也就是说,便携式咒语是:

sed "1s/=[^,][^,]*//g; s/[^,][^,]*=//g"


)

嗨,托马斯,这很快。谢谢。但是sed-r出来说这是非法的选择。还有其他选择吗?很有趣,在这里对我有用。但是我在Linux上,所以你的sed可能是不同的版本。这是真的。我在办公室,面前的是Solaris。@TomasM:用
sed的/=[^,]\{1,\}//g'
替换第一个sed命令,用
sed的/[^,]\{1,\}=//g'
替换第二个sed命令,以便与GNU和Solaris的sed一起使用。请说明您的sed版本。感谢您使用哪一版本的Solaris?摆脱混淆的
并发布一个完整的、可测试的示例。很抱歉,Ed。这些只是为了表明字段的数量未知。因此,提取完全基于模式匹配,而不考虑字段的数量/名称。我理解其意图,但找到其他方式来表达您的需求,而不是把应该简单明了的内容弄乱,可测试的示例输入/输出,文本实际上并不存在,我们在为您测试建议的解决方案时必须以某种方式进行处理。请尝试“sed--help”,并查看哪些参数具有“在脚本中使用扩展正则表达式”的描述…然后使用该参数…-e-f和-n仅受支持。是否有其他选项去掉-r选项..并且应该可以正常工作,因为模式实际上也是,行中的字段未知。这就是问题所在。如果你再看到我的问题,你会注意到的。因此,如果知道专栏,那么这很好。我的道歉使用我编辑的回答中的下一个解决方案。事实上,我已经想到了上面的伪代码,但在语法上无法实现它。令人惊讶的是,我很赞同托马斯和塞勒斯提到的解决方案,因为它只需要一行代码。不过,非常感谢。不,发布的cat+head+sed解决方案不需要一行代码,它使用UOOC,使用多个工具+管道,只需要对文件进行两次传递,如果您的输入来自流而不是文件,它将不起作用。祝你好运对的这就是为什么,我使用了注释部分中提到的一个,首先我在文件上做了sed的//=[^,]\{1,\}//g',它取出了头,第二个sed的//[^,]\{1,\}=//g',它取出了所有的值。我觉得这很酷,对吗?:)无论您是使用您选择的答案中的sed命令,还是使用下面注释中的sed命令,我上面的注释都适用。显然,如果您愿意,可以使用它,只要您不担心效率、可重用性、可增强性等。它应该可以正常工作;cat | sed
方法发布在另一个答案中,我编辑了我的答案,以在awk中显示等效的方法。请您将所有替代方法放在这里好吗?我不支持使用solaris和-r和-E。
$ cat tst.awk
BEGIN { FS="[,=]"; OFS="," }
NR==1 {
    for (i=1;i<NF;i+=2) {
        printf "%s%s", $i, (i<(NF-1) ? OFS : ORS)
    }
}
{
    for (i=2;i<=NF;i+=2) {
        printf "%s%s", $i, (i<NF ? OFS : ORS)
    }
}

$ awk -f tst.awk file
id,name,age
1234,abcd,76
4323,asdasd,43
$ awk 'NR==1{h=$0;gsub(/=[^,]+/,"",h);print h} {gsub(/[^,]+=/,"")} 1' file
id,name,age
1234,abcd,76
4323,asdasd,43
sed -r '1s/=[^,]+//g; s/[^,]+=//g'
sed "1s/=[^,][^,]*//g; s/[^,][^,]*=//g"