我有以下数据作为输入:
A 1,2
B 3,2,5
C 6,7
D 1,3,5,8
如何使用 AWK 获得以下输出?
A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8
答案1
$ awk -F '[ ,]' '{ for (i = 2; i <= NF; ++i) print $1, $i }' file
A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8
这将行视为由空格或逗号分隔的字段组成。对于每一行,awk
程序都会迭代第二个字段,直到该行的末尾。对于每个字段,它输出第一的行上的字段与当前字段一起。
答案2
awk '{gsub(/,/, "\n" $1 " "); print}' file
在此解决方案中,我们只是将每个“ ,
”替换为"\n$1 "
答案3
使用sed
启用的扩展正则表达式引擎,我们可以执行如下操作:
$ sed -re '
s/^((\S+\s+)[^,]+),/\1\n\2/
P;D
' file
我们Perl
可以这样做:
$ perl -F'\s+|,' -lane '
print join $", splice @F, 0, 2, $F[0] while @F > 1;
' file
按空格或逗号分割当前记录,并将其存储在零索引数组中@F
。
拼接数组的前两个元素并用单个空格将它们连接起来$"
并打印它们。同时将两个删除的元素替换为第一个元素。重复此过程,直到只剩下一个元素。
答案4
如果sed
是一个选项,你可以这样做:
sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/; ta' infile
考虑以下输入:
B 2,3,5,6
C 6,7
D 1,3,5,8
- 这
([^ ]* )
捕获第一列(假设空格是分隔符);它将捕获B
(乙随后是一个空间)。 - 这
(.*),
捕获了直到最后一个逗号出现之前的所有内容;它将捕获2,3,5
这
([^,]*$)
捕获了该行的其余部分(即:每次最后一个逗号之后的最后一个字段);它将捕获6
因此
\1\2\n\1\3
第一行的第一次循环运行时的结果如下:sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/;q ;ta' infile B 2,3,5 B 6
下一个循环运行结果如下:
B 2,3 B 5 B 6
- 下次运行...
最后在最后一次循环运行中第一行将输出如下:
sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/ ;ta ;q' infile B 2 B 3 B 5 B 6
现在阅读下一行并执行相同的过程,直到所有行都继续并完成。