2017-08-05 45 views
1

通過一個REST API端點,我得到相當大的CSV文件結構如下(JSON內CSV文件):JSON在CSV以CSV

A,B,C,D 
1,2,3,{"E":1,"F":2,"G":3} 
1,2,3,{"E":1,"H":2} 

對於不同的工具,我需要一個CSV與平結構(沒有嵌套的JSON)。所以,最後,我想要一個看起來像這樣的CSV。

A,B,C,E,F,G,H 
1,2,3,1,2,3, 
1,2,3,1,,,2 

(雖然列標題看起來層次分明,這不是對我的使用情況很重要)

由於CSV文件是相當大的,我在尋找一個相對高性能的方式來做到這一點。我將用JavaScript編寫(Node.JS)(因爲這是用於腳本所有其他部分的語言)。然而,現在我只是尋找一種理論方式/僞代碼來執行這種操作。

據我所知,我可能不得不遍歷CSV文件兩次。我第一次只需要獲取所有JSON密鑰。第二次,我可以創建一個新的CSV文件並設置所有值。但是,我會正確地找出哪一列我必須寫出值?

或者更高性能的將CSV文件「轉換」爲一個循環中的一個對象數組,然後使用類似CSV解析器(http://csv.adaltas.com/)將其轉換回CSV?

回答

0
var express = require('express'); 
var app = express(); 
var bodyParser = require('body-parser'); 
var mysql=require('mysql'); 
var fs= require('fs'); 
var csv = require('fast-csv'); 
var formidable = require('formidable'); 
var urlencodedParser = bodyParser.urlencoded({ extended: false }) 
var con=mysql.createConnection({ 
host:'localhost', 
user:'dheeraj', 
password:'123', 
database:'dheeraj' 
}); 
app.use('/assets',express.static('assets')); 
app.get('/d', function (req, res) { 
    res.sendFile(__dirname + "/" + "/d.html"); 
}) 

app.post('/file_upload', urlencodedParser, function (req, res) { 

    //{ 
    var form = new formidable.IncomingForm(); 
    form.parse(req, function (err, fields, files) { 
    res.write('File uploaded'); 
    //console.log(files.filetoupload); 

    fs.createReadStream(files.filetoupload.name) 
     .pipe(csv()) 
     .on('data',function(data){ 
     var d1=data[0]; 
      var d2=data[1]; 
      var d3=data[2]; 
       var d4=data[3]; 
       var d5=data[4]; 
     con.query('insert into demo values(\''+d1+'\',\''+d2+'\',\''+d3+'\',\''+d4+'\',\''+d5+'\')',function(err,result) 
      { 
       console.log('inserted'); 
      }) 
     console.log(data); 
     }) 
     .on('end',function(data){ 
     console.log('read finished'); 
     }); 

    res.end(); 

}) 
}) 

var server = app.listen(8081, function() { 
var host = server.address().address 
var port = server.address().port 

console.log("Example app listening at http://%s:%s", host, port) 

}) 
+0

這是我上傳一個csv文件到頁面並檢索可插入到我的數據庫的數據的代碼。我希望它能幫助你。 –

+0

謝謝,但這並不能解決我的問題,因爲我的CSV數據中也包含JSON數據。 – Daniel

1

下面是使用jq

一個解決方案,如果該文件filter.jq包含

[ 
    split("\n")             # split string into lines 
| (.[0] | split(",")) as $headers       # split header 
| (.[1:][] | split(","))          # split data rows 
| select(length>0)            # get rid of empty lines 
| $headers[:-1] as $h1           # fixed headers 
| .[:($h1|length)] as $p1          # fixed part 
| .[($h1|length):] as $p2          # variable part 
| (
    [ [ $h1, $p1 ]           # \ 
     | transpose[]           # \ assemble fixed object 
     | {key:.[0], value:.[1]|tonumber}      #/from fixed keys and values 
    ] | from_entries           #/
) + (
    $p2 | join(",") | fromjson        # assemble variable object 
) 
] 

| (map(keys) | add | unique) as $all       # compute final headers 
| [$all] + (             # add headers to 
     map(. as $b | reduce $all[] as $a ([];. + [$b[$a]])) # objects with all keys 
    | map(map(if . == null then "" else tostring end))  # convert values to strings 
) 
| .[]               # scan final array 
| @csv               # convert to csv 

,你的數據是在一個名爲data文件,然後

jq -M -R -s -r -f filter.jq data 

會產生

"A","B","C","E","F","G","H" 
"1","2","3","1","2","3","" 
"1","2","3","1","","","2"