HanningWu
V2EX  ›  Node.js

如何使用 nodejs 删除本地文件前 1000 行内容?

  •  
  •   HanningWu · Apr 5, 2017 · 6763 views
    This topic created in 3499 days ago, the information mentioned may be changed or developed.

    我是一个 nodejs 新手,由于某种原因必须利用 nodejs 简单快速地写一个处理文件内容的小小 app 。我看过 nodejs documentation ,有些懵逼,所以偷个懒来 V 站问一下大家。。

    目的是想读取一个包含超多行数的文件,并对每一行内容做一些操作。如果全部读取的话内存不够,打算用一个循环去读取文件内容,每次读 1000 行,对这 1000 行数据进行一些处理之后,删除原文件前 1000 行内容,保证下一次循环不重复读取内容。

    有没有人能告诉我删除本地文件的前 1000 行在 nodejs 中该如何实现?

    PS. 我试过 nodejs 的 readStream 模块去一行一行地读取。但是这个方法有一些小毛病,我不想考虑了。如果可以的话,能帮忙解决一下我问的上一个问题也可:请问如何使用 nodejs 的 readline 模块按行读取文件内容然后依次更新到 html 页面中?

    PS 的 PS. 如果能用 shell script 做是超简单的,一个 sed -i '1,1000d' filename.txt 就搞定了,然而不得不用 nodejs。。

    31 replies  •  2017-04-07 21:45:37 +08:00
    xcatliu
    xcatliu
    Apr 5, 2017 via iPhone
    1
    可以用 node 开子进程执行 shell ?
    HanningWu
    HanningWu
    OP
    Apr 5, 2017
    2
    @xcatliu 我需要在 Windows 下用 node-webkit 写 web app , Windows 下可以用 shell 子进程不?
    xcatliu
    xcatliu
    Apr 5, 2017 via iPhone❤️1
    4
    xcatliu
    xcatliu
    Apr 5, 2017 via iPhone
    5
    @HanningWu 可以跨平台执行 shell 命令
    123s
    123s
    Apr 5, 2017 via Android
    6
    我怎么感觉方向不对
    MicroPan
    MicroPan
    Apr 5, 2017❤️1
    7
    node readline 模块 + socket.io
    readline 模块实现按行读文件
    socket.io 实现 客户端和服务器 交互
    cxbig
    cxbig
    Apr 5, 2017 via iPhone❤️1
    8
    这种事用 shell

    linux:
    sed -i -n '1,1000d' your_file

    mac:
    sed -i '' -n '1,1000d' your_file
    HanningWu
    HanningWu
    OP
    Apr 5, 2017
    9
    @MicroPan 没有接触过 socket.io ,不想现学了。
    HanningWu
    HanningWu
    OP
    Apr 5, 2017
    10
    @xcatliu 这个 shelljs 看起来很棒啊,我对 shell script 很熟,如果能在 nodejs 里执行 shell script 就太好啦。我马上去试试,超感谢。
    billlee
    billlee
    Apr 5, 2017
    11
    你这个思路不对啊。不可能从一个文件的头部删除一千行,能实现的方法都是把 1000 行后的内容写到新文件,然后用新文件覆盖掉旧文件
    imxieke
    imxieke
    Apr 5, 2017 via Android
    12
    @cxbig 那不对啊 前 1000 行读出来了 第二个一千行不行啊。
    quickma
    quickma
    Apr 5, 2017
    13
    哇, sheeljs ,现在这个 js 啊,真的搞事情。
    newdongyuwei
    newdongyuwei
    Apr 5, 2017
    14
    如果“目的是想读取一个包含超多行数的文件,并对每一行内容做一些操作”,那无论你文件多大, nodejs 都可以轻松处理啊! nodejs 可以流式读取文件, see https://nodejs.org/dist/latest-v7.x/docs/api/fs.html#fs_fs_createreadstream_path_options 再参考这个 https://nodejs.org/dist/latest-v7.x/docs/api/stream.html#stream_class_stream_readable 监听 data 事件就可以处理目标数据了。
    victory
    victory
    Apr 5, 2017
    15
    @cxbig 牛 PowerShell 这么做
    cxbig
    cxbig
    Apr 5, 2017
    16
    @victory PowerShell 不会,我只会 Mac 和 Linux 的方法
    cxbig
    cxbig
    Apr 5, 2017
    17
    @imxieke 我上面这个命令带上 -i 就直接删除该文件最前面的 1 千行

    如果你要读指定行的话,可以用参数 p ,这命令直接输出到 stdout ,怎么接收看你了
    sed -n '1001,2000p' your_file
    klesh
    klesh
    Apr 5, 2017 via Android
    18
    windows 下是没有原生 shell 的,参考 14 楼的方法现实些, readline 包也是可以的。
    willakira
    willakira
    Apr 6, 2017
    19
    删掉原始文件出问题的时候真是会欲哭无泪,比较推荐 stream 读取然后写到新文件
    HanningWu
    HanningWu
    OP
    Apr 6, 2017
    20
    @newdongyuwei 我用了 readline 模块,用的是 html 页面中一个按钮(button)的 onclick 事件去触发这个基于 readline 模块的文件读取函数。但是我对每一行的处理包括一行修改 html 文件内容的命令。比如 html 页面中有个 <p id="status"><p>。我希望每读取一行之后就利用 document.getElementById("status").innerHTML = line 覆盖 id="status" 的段落原有内容为该行内容。但点击按钮之后,触发文件读取函数这时候页面卡住了,然后等函数运行结束,页面才恢复正常,于是我只看到了最后一行的显示内容。运气过程中“上一行内容被新的一行的内容覆盖”这个显示效果我就看不到了。
    HanningWu
    HanningWu
    OP
    Apr 6, 2017
    21
    @newdongyuwei 最终,是需要实现这样一个效果,示例代码: https://jsfiddle.net/09kuyn7v/ 。但不是像这个示例中那样,数据从数组中来,我需要的是从文件每一行读取出来,然后以同样的效果通过点击按钮显示到 html 的一个段落中去。
    param
    param
    Apr 6, 2017 via Android
    22
    @cxbig 为什么 Mac 多个双引号,是干嘛的
    HanningWu
    HanningWu
    OP
    Apr 6, 2017 via iPhone
    23
    @param 那不是双引号,是两个单引号,用来备份 -i 直接修改的文件。比如你利用 sed -i '.bak' '1,100d' filename.txt 命令去删除 filename.txt 的前 100 行,中端会先备份文件为 filename.txt.bak
    HanningWu
    HanningWu
    OP
    Apr 6, 2017 via iPhone
    24
    @param 单引号内放空,看起来像双引号时就不备份
    HanningWu
    HanningWu
    OP
    Apr 6, 2017
    25
    @newdongyuwei 那看是怎么“轻松处理”,我的确可以用 readStrem 来读文件,但是我遇到的问题是读取文件之后无法**动态地依次**显示到 html 页面中去!
    cxbig
    cxbig
    Apr 6, 2017
    26
    @param 那是两个单引号,这个参数是用来定义重命名后缀的, 23 楼已说明
    当你想直接写回原文件的时候, Linux 只写 -i 就好, Mac 下必须要带空字符串当参数,不然报错
    IJustmaogepao
    IJustmaogepao
    Apr 6, 2017
    27
    我的想法是可以用 readFile 读出来,再用 split('\n')切割成数组,然后去掉前 1000 个元素。。
    123s
    123s
    Apr 6, 2017 via Android
    28
    @IJustmaogepao 发文件就坑了
    123s
    123s
    Apr 6, 2017 via Android
    29
    大文件
    WXYOO1
    WXYOO1
    Apr 7, 2017
    30
    推荐使用 line-reader 这个包 直接读行,前 1000 行不处理,后面开始写入新文件
    ```
    var lineReader = require('line-reader');

    lineReader.eachLine('file.txt', function(line, last) {
    console.log(line);
    });
    ```
    HanningWu
    HanningWu
    OP
    Apr 7, 2017
    31
    @WXYOO1 这个包读取文件是同步的还是异步的?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5098 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 173ms · UTC 06:40 · PVG 14:40 · LAX 22:40 · JFK 01:40
    ♥ Do have faith in what you're doing.