csv 将单列转换为多列,确保列数在最后一行

uz75evzq  于 2023-01-10  发布在  其他
关注(0)|答案(3)|浏览(215)

我想使用AWK(Windows)将一个文本文件从一列转换为多列-在脚本或命令行中指定的计数。
此问题has been asked before,但我的最终数据文件需要始终具有相同的列数。
输入示例:

L1
L2
L3
L4
L5
L6
L7

分为3列和“;“作为分隔符

L1;L2;L3
L4;L5;L6
L7;;        <<< here two empty fields are created after end of file, since I used just one on this line.

我试图修改给出的典型解决方案的变体:NR%4 {printf $0",";next} 1;和一个计数器,但不能完全正确。
我不希望在此之前计算行数,因为这样会多次遍历文件。

elcex8rz

elcex8rz1#

您可以使用以下awk解决方案:

awk -v n=3 '{
   sub(/\r$/, "")   # removes DOS line break, if present
   printf "%s", $0(NR%n ? ";" : ORS)
}
END {
   # now we need to add empty columns in last record
   if (NR % n) {
      for (i=1; i < (n - (NR % n)); ++i)
         printf ";"
      print ""
   }
}' file

L1;L2;L3
L4;L5;L6
L7;;
e0bqpujr

e0bqpujr2#

使用您展示的示例,请尝试以下awk代码。使用xargs + awk组合来实现OP所需的结果。

xargs -n3 < Input_file | 
awk -v OFS=";" '{if(NF==1){$0=$0";;"};if(NF==2){$0=$0";"};$1=$1} 1'
iih3973s

iih3973s3#

对于awk,我会:

awk -v n=3 '
{printf("%s%s", $0, (NR%n>0) ? ";" : ORS)}
END{
    for(i=NR%n; i<n-1; i++) printf(";")
    printf ORS
}' file

或者,另一个awk

awk -v n=3 -v OFS=";" '
{ row=row ? row FS $0 : $0 }           # build row of n fields
!(NR%n) {$0=row; NF=n; print; row="" } # split the fields sep by OFS
END { if (NR%n) { $0=row; NF=n; print } }  # same
' file

如果您需要更多选项,也可以使用ruby

ruby -le '
n=3
puts $<.read.
    split($/).
    each_slice(n).
    map{|sl| sl.fill(sl.size...n) { "" }; sl.join(";") }.
    join($\) # By using $\ and $/ with the -l the RS and ORS is set correctly for the platform
' file

或者,要知道paste就是为此设计的:

paste -d';' - - - <file

(Use对于所需的每一列为-
以下任何一种打印(带有n=3):

L1;L2;L3
L4;L5;L6
L7;;

(And对于n的其他值也能正常工作...)

相关问题