Перейти к синтаксическому анализу CSV-файла

#csv #parsing #go #io

#csv #синтаксический анализ #Вперед #io

Вопрос:

Я пытаюсь выполнить действительно простой синтаксический анализ CSV-файла, но по какой-то причине он считывает только самую последнюю строку файла.

Я пробовал использовать reader.ReadAll()

 package main

import (
     "encoding/csv"
     "fmt"
     "os"
)

func main() {

     csvfile, err := os.Open("somecsvfile.csv")

     if err != nil {
             fmt.Println(err)
             return
     }

     defer csvfile.Close()

     reader := csv.NewReader(csvfile)

     reader.FieldsPerRecord = -1 // see the Reader struct information below

     rawCSVdata, err := reader.ReadAll()

     if err != nil {
             fmt.Println(err)
             os.Exit(1)
     }

     // sanity check, display to standard output
     for _, each := range rawCSVdata {
             fmt.Printf("email : %s and timestamp : %sn", each[0], each[1])
     }
}
  

И я попробовал только простой reader.Read() из этого фрагмента

 for {
    row, err := csvr.Read()
    if err != nil {
        if err == io.EOF {
            err = nil
        }
    }
    fmt.Println(row)
}
  

Оба этих фрагмента, которые я нашел в Интернете, кажутся действительно простыми. Пакет CSV, похоже, также точно описывает то, что я хочу ( ReadAll() следует прочитать весь CSV в фрагмент строкового фрагмента).

Файлы CSV тоже выглядят совершенно нормально. Загрузка одного онлайн у меня есть ниже (каждая строка представляет собой отдельную запись, за исключением первой строки).
Что я делаю не так?

 street,city,zip,state,beds,baths,sq__ft,type,sale_date,price,latitude,longitude
3526 HIGH ST,SACRAMENTO,95838,CA,2,1,836,Residential,Wed May 21 00:00:00 EDT 2008,59222,38.631913,-121.434879
51 OMAHA CT,SACRAMENTO,95823,CA,3,1,1167,Residential,Wed May 21 00:00:00 EDT 2008,68212,38.478902,-121.431028
  

Редактировать:
Я думаю, что я выяснил, что происходит не так. В приведенном ниже коде, если я изменю fmt.Print(col) значение на fmt.Println(col) , я в конечном итоге напечатаю каждый столбец каждой строки. Если я оставлю это как fmt.Print(col) , я напечатаю только 1 строку. Кто-нибудь знает, почему это происходит?
Я думал Print и Println() действовал так же, просто println() добавлял новую строку?

      // sanity check, display to standard output
     for _, row := range rawCSVdata {
            for _, col := range row {
                    _,err := fmt.Print(col)
                    if err != nil {
                            fmt.Println(err)
                    }
            }
            fmt.Println("")
     }
  

Комментарии:

1. версия ReadAll () должна была работать, какой результат вы получили при ее использовании?

2. вы уверены, что он не печатает все строки в 1 строке?

3. Итак, что произошло, так это то, что мой csv-файл отображал столько строк, если я открывал его в текстовом редакторе, таком как Sublime, но на самом деле это была всего 1 строка, разделенная символом «^ M» в vim. Когда я просто использовал Print, он печатал только самую последнюю строку (потому что она слишком длинная для печати каждой отдельной строки). Так что да, просто глупая ошибка с моей стороны

Ответ №1:

При использовании fmt.Print(col) внутреннего for цикла вам необходимо добавить пробел после ваших данных, например fmt.Print(i, " ") (попробуйте на Go Playground):

 package main

import "fmt"    

func main() {
    for i := 0; i < 10; i   {
        fmt.Print(i)
    }
}
  

вывод:

 0123456789
  

Это работает нормально, попробуйте на Go Playground:

 package main

import (
    "encoding/csv"
    "fmt"
    "strings"
)

func main() {
    reader := csv.NewReader(strings.NewReader(str))
    reader.TrimLeadingSpace = true
    reader.FieldsPerRecord = -1 // see the Reader struct information below
    rawCSVdata, err := reader.ReadAll()
    if err != nil {
        panic(err)
    }
    for _, each := range rawCSVdata {
        //fmt.Println(each)
        fmt.Printf("%-15q %-150q n", each[0], each[1])
    }
    fmt.Println()
    for _, row := range rawCSVdata {
        for _, col := range row {
            //fmt.Print(col)
            fmt.Printf("0q ", col)
        }
        fmt.Println("")
    }
}

var str = `street,city,zip,state,beds,baths,sq__ft,type,sale_date,price,latitude,longitude
    3526 HIGH ST,SACRAMENTO,95838,CA,2,1,836,Residential,Wed May 21 00:00:00 EDT 2008,59222,38.631913,-121.434879
    51 OMAHA CT,SACRAMENTO,95823,CA,3,1,1167,Residential,Wed May 21 00:00:00 EDT 2008,68212,38.478902,-121.431028`
  

вывод:

 "street"        "city"                                                                                                                                                 
"3526 HIGH ST"  "SACRAMENTO"                                                                                                                                           
"51 OMAHA CT"   "SACRAMENTO"                                                                                                                                           

                      "street"                         "city"                          "zip"                        "state"                         "beds"                        "baths"                       "sq__ft"                         "type"                    "sale_date"                        "price"                     "latitude"                    "longitude" 
                "3526 HIGH ST"                   "SACRAMENTO"                        "95838"                           "CA"                            "2"                            "1"                          "836"                  "Residential" "Wed May 21 00:00:00 EDT 2008"                        "59222"                    "38.631913"                  "-121.434879" 
                 "51 OMAHA CT"                   "SACRAMENTO"                        "95823"                           "CA"                            "3"                            "1"                         "1167"                  "Residential" "Wed May 21 00:00:00 EDT 2008"                        "68212"                    "38.478902"                  "-121.431028"