为了账号安全,请及时绑定邮箱和手机立即绑定

将 2 个大的排序 CSV 文件合并为一个文件

将 2 个大的排序 CSV 文件合并为一个文件

Go
慕码人2483693 2021-06-04 18:08:50
我有一个大小约为 50GB 的存档文件。每周,我都必须将一个 CSV 文件与非常大的 50GB CSV 文件合并。我是 Go 的新手,希望在 Go 中有一个不错的 elagent 解决方案。这些文件看起来像:"a:123", 101010"b:123", 101010"some-key-here:123", 101010"some-key-here:234", 101010
查看完整描述

2 回答

?
繁华开满天机

TA贡献1816条经验 获得超4个赞

虽然我没有自己编译它来检查,但一旦你实现了这个compare()功能,这应该可以做你想做的。它本质上是 Mergesort 算法的“合并”步骤。由于您已经按排序顺序获得了两个文件,因此您只需要合并步骤,这可以以流式方式完成。


package main


import (

    "encoding/csv"

    "io"

    "log"

    "os"

)


const outFile = "your/output/file/path.ext"


func main() {

    // make sure there are only 2 args

    if len(os.Args) != 3 {

        log.Panic("\nUsage: command file1 file2")

    }


    // open the first file

    f1, e := os.Open(os.Args[1])

    if e != nil {

        log.Panic("\nUnable to open first file: ", e)

    }

    defer f1.Close()


    // open second file

    f2, e := os.Open(os.Args[2])

    if e != nil {

        log.Panic("\nUnable to open second file: ", e)

    }

    defer f2.Close()


    // create a file writer

    w, e := os.Create(outFile)

    if e != nil {

        log.Panic("\nUnable to create new file: ", e)

    }

    defer w.Close()


    // wrap the file readers with CSV readers

    cr1 := csv.NewReader(f1)

    cr2 := csv.NewReader(f2)


    // wrap the out file writer with a CSV writer

    cw := csv.NewWriter(w)


    // initialize the lines

    line1, b := readline(cr1)

    if !b {

        log.Panic("\nNo CSV lines in file 1.")

    }

    line2, b := readline(cr2)

    if !b {

        log.Panic("\nNo CSV lines in file 2.")

    }


    // copy the files according to similar rules of the merge step in Mergesort

    for {

        if compare(line1, line2) {

            writeline(line1)

            if line1, b = readline(cr1); !b {

                copy(cr2, w)

                break

            }

        } else {

            writeline(line2)

            if line2, b = readline(cr2); !b {

                copy(cr1, w)

                break

            }

        }

    }


    // note the files will be closed here, since we defered it above

}


func readline(r csv.Reader) ([]string, bool) {

    line, e := r.Read()

    if e != nil {

        if e == io.EOF {

            return nil, false

        }

        log.Panic("\nError reading file: ", e)

    }

    return line, true

}


func writeline(w csv.Writer, line []string) {

    e := w.Write(line)

    if e != nil {

        log.Panic("\nError writing file: ", e)

    }

}


func copy(r csv.Reader, w csv.Writer) {

    for line, b := readline(r); !b; r, b = readline(r) {

        writeline(w, line)

    }

}


func compare(line1, line2 string) bool {

    /* here, determine if line1 and line2 are in the correct order (line1 first)

       if so, return true, otherwise false

    */

}


查看完整回答
反对 回复 2021-06-07
?
LEATH

TA贡献1936条经验 获得超6个赞

如果这两个文件是单独排序的,那么您可以使用合并排序的合并功能将它们组合成一个排序数组。

通过数组,我的意思是我们可以使用另一个 CSV 文件即时写入排序的数据。


查看完整回答
反对 回复 2021-06-07
  • 2 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号