【问题标题】:How to format data-logger results as JSON?如何将数据记录器结果格式化为 JSON?
【发布时间】:2021-12-11 06:48:50
【问题描述】:

我有一个数据记录器,它通过附加到文件来记录时间、状态和温度。 (记录器是从 cron 作业中调用的。)

如果我可以将数据以 JSON 格式读入网页脚本,那就太好了,但我看不出有什么好的方法——要么我的记录器更复杂,要么我的阅读器更复杂。

我的数据是这样的:

[ timestamp, "status", temperature ]
[ 123456789, "sync",   12345]

我可以很容易地在行尾添加逗号,但无论哪种方式,它都不是格式良好的 JSON —— 你需要将整个内容括起来。

所以要么我的记录器必须检测到一个空的数据文件并添加一个前括号,再加上寻找到末尾,备份一个字符,用逗号替换最后一个右括号,然后用一个额外的结束附加它自己的记录括号,或者读者必须通过切掉尾随逗号并在周围添加括号来按摩 pre-JSON。

有更简单的方法吗?

【问题讨论】:

    标签: javascript json formatting


    【解决方案1】:

    您使用的格式与既定且非常适合记录的格式相似:请参阅JSON Lines 和ndjson。

    通过在第一行之后对输入进行切片,您将得到 JSON 行。然后你只需要迭代这些行并解析每一行(如果需要,可以选择收集到一个数组中)。

    这是一个例子:

    const LF = '\n';
    
    function iterateJSONLines (jsonl, cb) {
      for (const line of jsonl.trim().split(LF)) {
        cb(JSON.parse(line));
      }
    }
    
    /** handle the first (non-JSON) line in your input */
    function separateHeaderFromJSONLines (input) {
      for (let i = 0; i < input.length; i += 1) {
        if (input[i] !== LF) continue;
        return [input.slice(0, i).trim(), input.slice(i + 1)];
      }
    }
    
    function main (input) {
      const [headerLine, jsonl] = separateHeaderFromJSONLines(input);
      const arr = [];
      iterateJSONLines(jsonl, arr.push.bind(arr));
      console.log(headerLine);
      console.log(arr);
    }
    
    const input = `[ timestamp, "status", temperature ]
    [ 123456789, "sync",   12345]
    [ 987654321, "anotherStatus",   54321]
    `;
    
    main(input);

    【讨论】:

    • 我希望我能懒一点——我的文件很大,我需要它们作为一个数组,所以我想做$.getJSON( 'url', func )。不过,我修改了日志程序以进行必要的搜索和覆盖,但这并不是那么可怕(除了搜索和覆盖,这有点脆弱)。谢谢!
    • 再看一遍,我认为你指向JSON Lines 的指针是关键...我可以使用sed 制作一个完整的JSON 文件,但是stream-edit-to-new,移动-new-to-old dance 是愚蠢的、耗时的,并且使用的磁盘空间是仅追加一行的两倍。当我将文件加载到浏览器中时,我有更多的能力来按摩东西,所以这是有意义的。
    【解决方案2】:

    你可以这样做

    我会使用fetch

    const str = `[ timestamp, "status", temperature ]
    [ 123456789, "sync",   12345]`
    
    const data = str.split(/\r?\n/) // line feed
      .map(line => line
        .replace(/[\[\]]/g,"") // remove square brackets (can be done in the regex below too
        .match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) // find stuff with or without quotes
        .map(elem => isNaN(elem) ? elem : +elem) // convert numbers back to numbers
      );
    console.log(data)

    【讨论】:

      猜你喜欢
      • 2011-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多