如何使用 nodejs 删除本地文件前 1000 行内容? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
HanningWu

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

  •  
  •   HanningWu 2017 年 4 月 5 日 6293 次点击
    这是一个创建于 3306 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我是一个 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 条回复    2017-04-07 21:45:37 +08:00
    xcatliu
        1
    xcatliu  
       2017 年 4 月 5 日 via iPhone
    可以用 node 开子进程执行 shell ?
    HanningWu
        2
    HanningWu  
    OP
       2017 年 4 月 5 日
    @xcatliu 我需要在 Windows 下用 node-webkit 写 web app , Windows 下可以用 shell 子进程不?
    viko16
        3
    viko16  
       2017 年 4 月 5 日 via Android   1
    xcatliu
        4
    xcatliu  
       2017 年 4 月 5 日 via iPhone   1
    xcatliu
        5
    xcatliu  
       2017 年 4 月 5 日 via iPhone
    @HanningWu 可以跨平台执行 shell 命令
    123s
        6
    123s  
       2017 年 4 月 5 日 via Android
    我怎么感觉方向不对
    MicroPan
        7
    MicroPan  
       2017 年 4 月 5 日   1
    node readline 模块 + socket.io
    readline 模块实现按行读文件
    socket.io 实现 客户端和服务器 交互
    cxbig
        8
    cxbig  
       2017 年 4 月 5 日 via iPhone   1
    这种事用 shell

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

    mac:
    sed -i '' -n '1,1000d' your_file
    HanningWu
        9
    HanningWu  
    OP
       2017 年 4 月 5 日
    @MicroPan 没有接触过 socket.io ,不想现学了。
    HanningWu
        10
    HanningWu  
    OP
       2017 年 4 月 5 日
    @xcatliu 这个 shelljs 看起来很棒啊,我对 shell script 很熟,如果能在 nodejs 里执行 shell script 就太好啦。我马上去试试,超感谢。
    billlee
        11
    billlee  
       2017 年 4 月 5 日
    你这个思路不对啊。不可能从一个文件的头部删除一千行,能实现的方法都是把 1000 行后的内容写到新文件,然后用新文件覆盖掉旧文件
    imxieke
        12
    imxieke  
       2017 年 4 月 5 日 via Android
    @cxbig 那不对啊 前 1000 行读出来了 第二个一千行不行啊。
    quickma
        13
    quickma  
       2017 年 4 月 5 日
    哇, sheeljs ,现在这个 js 啊,真的搞事情。
    newdongyuwei
        14
    newdongyuwei  
       2017 年 4 月 5 日
    如果“目的是想读取一个包含超多行数的文件,并对每一行内容做一些操作”,那无论你文件多大, 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
        15
    victory  
       2017 年 4 月 5 日
    @cxbig 牛 PowerShell 这么做
    cxbig
        16
    cxbig  
       2017 年 4 月 5 日
    @victory PowerShell 不会,我只会 Mac 和 Linux 的方法
    cxbig
        17
    cxbig  
       2017 年 4 月 5 日
    @imxieke 我上面这个命令带上 -i 就直接删除该文件最前面的 1 千行

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

    lineReader.eachLine('file.txt', function(line, last) {
    console.log(line);
    });
    ```
    HanningWu
        31
    HanningWu  
    OP
       2017 年 4 月 7 日
    @WXYOO1 这个包读取文件是同步的还是异步的?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2997 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 74ms UTC 02:19 PVG 10:19 LAX 19:19 JFK 22:19
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86