按行拆分csv文件并重新排列

时间:2016-12-07 03:39:38

标签: bash csv awk

我遇到的问题类似Split single column of csv horizontally in bash into multiple smaller csv files in BASH,其中的问题是分成不同的文件。我需要做类似的事情,但是在同一个文件中。

我正在使用bash,我有几个带有标题的csv文件,直到第27行。然后,一千行数据,然后另一个标题和另外一千行数据。但是,我会在这里简化:

**row1** Begin of header
...
**row26** TASK1, TASK2, DV-T1, DV-T2
**row27** --- End of header ---
**row28** 1, 111, 1, 991, 1, 1.1, 1, 9.1 
**row29** 2, 112, 2, 992, 2, 1.2, 2, 9.2 
**row30** 3, 113, 3, 993, 3, 1.3, 3, 9.3 
...
**row1028** 1000, 1128, 1000, 1028, 1000, 1.2, 1000, 10.2
**row1029** Begin of 2nd Header
...
**row1039** End of 2nd header 
**row1040** 1, 0.1, 1, 0.9 
**row1041** 2, 0.2, 2, 0.8
**row1042** 3, 0.3, 3, 0.7 
...
**row2040** 1000, 0.6, 1000, 0.6 
**row2041** End of 2nd data
**row2042** Performance, 0.87
**row2043** End of file

我希望将行拆分为1个csv文件,以便:

**row1** task1, dev-task1, task2, dev-task2, FractionT1-T2, Difference
**row2** 111, 1.1, 991, 9.1, 0.1, 0.9
**row3** 112, 1.2, 992, 9.2, 0.2, 0.8 
**row4** 113, 1.3, 993, 9.3, 0.3, 0.7 
...
**row1001** 1128, 1.2, 1028, 10.2, 0.6, 0.6

这就是我试图做的事情:

for strategy in *; do
    if [ -d "$strategy" ] ; then
        cd $strategy
        for file in *; do
            if [ -f "$file" ] ; then
                namefile=$(printf "${file/.csv/-output.csv}")
                #printf "$namefile\n"
                awk -F, 'BEGIN{print "task1, dev-task1, task2, dev-task2, FractionT1-T2, Difference"};NR > 27 && NR < 1029 { print $2 "," $6 "," $4 "," $8};NR > 1039 && NR < 2041 {print $2 "," $4 }' "$file" > "$namefile"
            fi
        done
    cd ..
    fi
done

但是,输出只是第一个命令,即

**row1** task1, dev-task1, task2, dev-task2, FractionT1-T2, Difference
**row2** 111, 1.1, 991, 9.1
**row3** 112, 1.2, 992, 9.2
**row4** 113, 1.3, 993, 9.3
...
**row1001** 1128, 1.2, 1028, 10.2

如何重新排列列?是否有必要通过粘贴-d&#34;为后一个合并创建两个文件; &#34; output1.csv output2.csv&gt;实时output.csv?我是否还可以将线性能( row2042 Performance,0.87)作为输出文件中的第2行?

1 个答案:

答案 0 :(得分:1)

这将成为awk脚本的稍微复杂的版本,我建议将其移至外部文件。

$ cat rearrange.awk
BEGIN   {
    FS=","
    OFS=FS
    print "task1, dev-task1, task2, dev-task2, FractionT1-T2, Difference"
}

# First data block: Collect the tasks and dev-tasks
NR > 27 && NR < 1029 {
    task1[NR-27] = $2
    task2[NR-27] = $4
    dtask1[NR-27] = $6
    dtask2[NR-27] = $8
}

# Second data block: Collect the fraction and differences
NR > 1039 && NR < 2041 {
    frac[NR-1039] = $2
    diff[NR-1039] = $4
}

# If we find a line that contains the performance, print it.
# Since we haven't printed anything beside the header yet, 
# This will be the second line.
/Performance/ {print}

# Reached the end of the file, now print everything.
END {
    for (i=1; i<=1001; i++) {
        print task1[i], dtask1[i], task2[i], dtask2[i], frac[i], diff[i]
    }
}
$ awk -f rearrange.awk $file > $namefile

这应该可以解决问题。基本上,awk在逐个记录的基础上工作。因此,当它到达文件的第二部分时,它已经完全处理了上一部分。

但是,如果我们将值添加到数组中,那么我们可以在最后访问数组。