在bash中的第n列之后将行转置到列

问题描述 投票:1回答:2

我有一个类似于以下格式的文件:

$ cat file_in.csv

1308123;28/01/2019;28/01/2019;22/01/2019
1308456;20/11/2018;27/11/2018;09/11/2018;15/11/2018;10/11/2018;02/12/2018
1308789;06/12/2018;04/12/2018  
1308012;unknown

从第二栏开始,我如何转置如下:

1308123;28/01/2019  
1308123;28/01/2019  
1308123;22/01/2019  
1308456;20/11/2018  
1308456;27/11/2018  
1308456;09/11/2018  
1308456;15/11/2018  
1308456;10/11/2018  
1308456;02/12/2018  
1308789;06/12/2018  
1308789;04/12/2018  
1308012;unknown

我正在测试我的脚本,但获得了错误的结果

echo "123;23/05/2018;24/05/2018" | awk -F";" 'NR==3{a=$1";";next}{a=a$1";"}END{print a}'

提前致谢

bash awk sed text-processing
2个回答
3
投票

第一个解决方案:Eaisest解决方案将循环遍历所有字段(当然,将字段分隔符设置为;)然后打印$1以及新行中的所有字段。另请注意,循环从i=2运行到NF的值离开第一个字段,因为我们需要从第2列开始在新行中打印。

awk 'BEGIN{FS=OFS=";"} {for(i=2;i<=NF;i++){print $1,$i}}'  Input_file


第二种解决方案:使用sub的1次替换(gsub)和全局替换(awk)功能。在这里我用;改变@@@的第一次出现(假设你的Input_file不会有这些字符在一起,以防它在那里选择任何独特的字符,而不是在一个的输入文件中代替@@@),然后全局替换;(所有出现)与ORS val(一个值为$ 1的变量)和;所以在新列中创建值。现在终于从第一场移除@@@。如果我们不用第一次出现的;替换任何其他角色,那么为什么我们已经完成了这个approch然后它会在我们不想要的替换之前放置一个新线。 (同样根据Ed先生的评论,此解决方案在1个Input_file中进行了测试,并且在读取多个Input_files时可能会出现问题)

awk 'BEGIN{FS=OFS=";"} {val=$1;sub(";","@@@");gsub(";",ORS val ";");sub("@@@",";",$1)} 1' Input_file

0
投票

另一个awk

awk -F";" '{ OFS="\n" $1 ";"; $1=$1;$1=""; printf("%s",$0) } ' file
© www.soinside.com 2019 - 2024. All rights reserved.