我的文件内容如下所示,并且想要转换我的输出,如下所示
输入
1,a,b,c 2,b,c 3,e,f 4,l
所需输出
1,a 1,b 1,c 2,b 2,c 3,e 3,f 4,l
第一个字段的值是唯一的,并且输入中第一个字段没有重复行。
我是脚本编写新手,不知道如何才能做到这一点。
答案1
您可以使用awk
并循环访问以 2 开头的字段:
awk -F, '{ OFS=FS; for (i=2;i<=NF;i++) print $1,$i }' file
输出:
1,a
1,b
1,c
2,b
2,c
3,e
3,f
4,l
答案2
有了sed
,你会做
sed -E 's/([^,]*,)([^,]*),/\1\2\n\1/;P;D' file
\n
请注意,在替换字符串中使用仅适用于 GNU sed
。在其他系统上,您需要使用实际的换行符,前面带有反斜杠:
sed -E 's/([^,]*,)([^,]*),/\1\2\
\1/;P;D' file
-E
表示扩展正则表达式,因此我可以()
使用\(\)
.只是为了可读性[^,]*
匹配不带逗号的字符串,因此它匹配一个字段- 因此,
[^,]*,[^,]*,
匹配前两个字段。我确实把()
这些字段放在周围,这样我就可以在替换中\1
重复使用它们\2
- 该
s
命令将前两个字段替换为自身,添加换行符并在新行中重复第一个字段。所以该行被分成两部分:1,a,b,c
一行为1,a
,另一行为1,b,c
- 现在
P
打印缓冲区中的第一行(我们知道它已经可以打印了) D
从缓冲区中删除第一行,如果删除后缓冲区中还有任何内容,则重新启动脚本。所以剩下的1,b,c
将再次分为1,b
和1,c
行。- 如果只剩下一个
x,y
,模式将不再匹配,因此不会插入换行符并且sed
不会循环,但将继续下一行
答案3
使用米勒(https://github.com/johnkerl/miller)
mlr --c2n --ofs "," --implicit-csv-header then reshape -r "[^1]" -o item,value then cut -x -f item input.txt
你将在输出中得到
1,a
1,b
1,c
2,b
2,c
3,e
3,f
4,l
答案4
尝试使用下面的命令,效果很好
count_line=`awk '{print NR}' p.txt| sort -nr| sed -n '1p'`
for((i=1;i<=$count_line;i++)); do j=`awk -v i="$i" -F "," 'NR==i{print $1}' p.txt`;k=`awk -v i="$i" -F "," 'NR==i{print NF}' p.txt`; for ((z=2;z<=$k;z++)); do awk -v i="$i" -v j="$j" -v z="$z" -F "," 'NR==i{print j","$z}' p.txt; done; done
输出
1,a
1,b
1,c
2,b
2,c
3,e
3,f
4,l