![根据第一列从现有列表生成新列表](https://linux22.com/image/155119/%E6%A0%B9%E6%8D%AE%E7%AC%AC%E4%B8%80%E5%88%97%E4%BB%8E%E7%8E%B0%E6%9C%89%E5%88%97%E8%A1%A8%E7%94%9F%E6%88%90%E6%96%B0%E5%88%97%E8%A1%A8.png)
我有一个以下格式的列表:
group1;visitor1,visitor2,visitor3,
group2;visitor4,visitor5
从上面的列表中,我需要通过以下方式生成一个列表:
group1,visitor1
group1,visitor2
group1,visitor3
group2,visitor4
group2,visitor5
答案1
这是非常如同对数组使用 AWK以及其他一些问题。主要思想是在第一个字段前面的单独行上打印从第二个字段开始的每个字段。
在本例中,我们指定字段分隔符为,
或;
,并且我们还确保不打印空字段(给定数据中第一行的末尾有一个空字段)。OFS
我们在命令行上设置的变量是-v
将用于分隔输出字段的输出分隔符字符串,并且NF
是该行上的字段数。
awk -F '[,;]' -v OFS=',' '{ for (i = 2; i <= NF; ++i) if ($i != "") print $1, $i }' file
给定问题中的数据,这会生成
group1,visitor1
group1,visitor2
group1,visitor3
group2,visitor4
group2,visitor5
答案2
这可以使用 GNU sed 来完成,如下所示:
sed -r 's:,$::;y:;,:,;:;:l;s:^(([^,]+)[^;]+);:\1\n\2,:;tl' file
对于每个输入行,我将删除尾随逗号(如果有),然后用分号切换逗号以帮助打印。之后,我在:l
和之间运行搜索和替换循环,tl
将组名称添加到当前输入行上的每个访问者前面。