根据第一个字段分割文件行

根据第一个字段分割文件行

我的文件内容如下所示,并且想要转换我的输出,如下所示

  • 输入

    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,b1,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

相关内容