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

时间:2019-03-12 23:52:30

标签: bash awk sed text-processing

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

$ 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}'

预先感谢

2 个答案:

答案 0 :(得分:3)

第一个解决方案: 最简便的解决方案是遍历所有字段(当然,将字段分隔符设置为;),然后打印{{1} }以及换行符中的所有字段。还要注意,循环从$1一直到i=2的值,直到第一个字段为止,因为我们需要从第二列开始打印新行。

NF


第二个解决方案: :使用awk 'BEGIN{FS=OFS=";"} {for(i=2;i<=NF;i++){print $1,$i}}' Input_file 的1个时间替换(sub)和全局替换(gsub)功能。在这里,我将awk的第一个出现更改为;(假设您的Input_file不会将这些字符放在一起,以防万一它选择了不在其Input_file中的任何唯一字符) @@@的位置,然后用@@@ val(值为$ 1的变量)和;全局替换ORS(所有出现),因此请在新列中赋值。现在,最后从第一个字段中删除;。如果我们不使用任何其他字符替换@@@的第一个出现的位置,为什么要执行此方法,那么它将在替换之前放置一个新行,而我们不希望有此行。 (此外,根据Ed先生的评论,此解决方案已在1个Input_file中进行了测试,并且在读取多个Input_file时可能会出现问题)

;

答案 1 :(得分:0)

另一个awk

 objArr.map(function(element) {
   element.data.basics.position = objArr.indexOf(element)
       element.data.basics.all= objArr.length, 
        return element;
     }
 )