有一個csv文件, 可是其中某些行的字段的值是一個json數組,數組的值又是json對象,內部有不少','
。html
這致使,在其它的數據分析工具中,沒法進行處理。node
如今咱們但願,把這個json數組拆分開來,取出內部的值,而後對於字段值不是json的則補空位,造成一個比較規整的表格。遍歷於後面分析。es6
最好的語言,是熟悉的語言。json
因此我用了js,固然由於是處理文件,因此確定是nodejs.api
不過熟悉是相對的,真正開始仍是要靠google。數組
大概的思路就是,使用readline
模塊,逐行讀取文件,而後對於每一行,首先使用split(,)
切分開來,而後對數組的長度進行判斷,數組長度超過規定值的,就是內部包含json數組的,由於json數組的位置,老是在第3個到導數第2個之間,使用slice()
函數,提取出來。而後把這個不規整的數組,用join()
拼成json
字符串,再解析出數組,提取出值,寫回去,對於正常的行,則使用一個固定的模式填補。函數
const readline = require('readline'); const fs = require('fs'); const os = require('os') let inputName = process.argv[2] || 'xxx.csv' // 輸入文件 let outputName = process.argv[3] || 'parse3 .csv' // 輸出文件 const reader = fs.createReadStream(inputName); const writer = fs.createWriteStream(outputName); const rl = readline.createInterface({ input: reader, output: writer }); let lineNum = 0; let 沒用的數 = 0; let padArray = ['null', 0, 'null', 0, 'null', 0] rl.on('line', (line) => { if (lineNum == 0) { lineNum++; return; // 跳過行頭 } let arr = line.split(','); if (arr.length > 5) { // 特殊狀況,含有json數組 let midArrRaw = arr.splice(3, arr.length - 4); // 取出json數組部分 let json = midArrRaw.join(','); // 拼成json字符串 let midArr = JSON.parse(json); // 解析json let newMidArr = [] for (let i = 0; i < midArr.length; i++) { let obj = midArr[i] for(let key in obj) { newMidArr.push(obj[key]) // 遍歷,解析出對象中的值, 這裏不保險,由於 for in 不保證順序,不過在這裏沒有問題 } } if (newMidArr.length !== 6) { console.log(newMidArr) throw new Error('error ' + lineNum + midArr) // 異常終止, 解析出來的數組長度應爲6 } arr.splice(3, 0, ...newMidArr); // 把數組插入到第3個位置。 ...是es6語法,把數組擴展開 } else { arr.splice(3, 1, ...padArray); // 正常狀況, 把補位數組插入 } writer.write(arr.join(',') + os.EOL) // 輸出, 這裏用','分割,若是','不行也能夠換別的,csv文件不必定要用','分割 沒用的數++; if (沒用的數 == 10000) { console.log(lineNum) // 輸出一下進度 沒用的數=0 } lineNum++; }); // close事件監聽 rl.on("close", function () { // 結束程序 console.log(lineNum) });
使用工具
require('os').EOL
來獲得操做系統範化的換行符。ui
令我疑問的是,不知道爲何不能夠直接利用readline模塊輸出。google
參考文獻: