在python中如何删除文件的某一行? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Sherlockhlt
V2EX    Python

在python中如何删除文件的某一行?

  •  
  •   Sherlockhlt 2012-11-05 15:29:13 +08:00 38690 次点击
    这是一个创建于 4727 天前的主题,其中的信息可能已经有所发展或是发生改变。
    网上看到的方法是把文件读成列表,然后把那一行删除,然后再写回文件。。如果是大文件效率就很低了,大家有更好的办法吗?
    23 条回复    2020-07-23 15:38:29 +08:00
    timonwong
        1
    timonwong  
       2012-11-05 15:46:07 +08:00
    mmap?
    zenomac
        2
    zenomac  
       2012-11-05 15:49:37 +08:00
    file对象没有删除一行的方法。

    语言上好像只能重写入。(才疏学浅啊)

    不如加一些标记作为作废一行的指示符。
    phuslu
        3
    phuslu  
       2012-11-05 16:01:19 +08:00
    试下这个, 没有完全读入内存
    with open('in.txt') as fp_in:
    with open('out.txt', 'w') as fp_out:
    fp_out.writelines(line for i, line in enumerate(fp_in) if i != 10)
    Sherlockhlt
        4
    Sherlockhlt  
    OP
       2012-11-05 16:07:40 +08:00
    @timonwong
    能说具体点吗?
    Sherlockhlt
        5
    Sherlockhlt  
    OP
       2012-11-05 16:08:47 +08:00
    @phuslu
    这个方法我也想过,不过还是有绕个大湾的感觉
    Sherlockhlt
        6
    Sherlockhlt  
    OP
       2012-11-05 16:09:41 +08:00
    @zenomac
    增加表示删除了没的这个标记后如何修改这个标记呢?
    hyq
        7
    hyq  
       2012-11-05 16:15:06 +08:00
    @Sherlockhlt 首先得定位到那一行行首在文件中的偏移地址a,然后需要判断这行的长度l,然后需要把a+l后的所有文本全部都向前移动l个字节.
    文本存储的时候不是链表结构的,我觉得在处理纯文本上已经没有更快的方法了
    phuslu
        8
    phuslu  
       2012-11-05 16:22:20 +08:00
    stackoverflow 的回答如下, 不过没测试过, 不清楚性能道理如何
    http://stackoverflow.com/questions/2329417/fastest-way-to-delete-a-line-from-large-file-in-python
    imom0
        9
    imom0  
       2012-11-05 16:28:23 +08:00
    013231
        10
    013231  
       2012-11-05 16:35:53 +08:00
    我在stackoverflow.com上了, 原地看似乎有好法:
    http://stackoverflow.com/q/13227970/805627
    不如果你可以把那行替成行(比如全空格的一行), 可以使用mmap:
    http://stackoverflow.com/a/2330081/805627
    http://www.doughellmann.com/PyMOTW/mmap/index.html

    @imom0 那是我的...
    clowwindy
        11
    clowwindy  
       2012-11-05 16:36:29 +08:00
    @phuslu 这个方法还可以改进一下,从跳过的行开始以 4K 为单位挪动后面的内容,而不是以行为单位。
    Sherlockhlt
        12
    Sherlockhlt  
    OP
       2012-11-05 16:49:53 +08:00
    @hyq
    试了下,最后要怎么改变文件大小呢?
    Sherlockhlt
        13
    Sherlockhlt  
    OP
       2012-11-05 16:50:31 +08:00
    @013231
    改成废弃一行其实直接fp.write()就可以了
    hyq
        14
    hyq  
       2012-11-05 16:53:15 +08:00
    @Sherlockhlt os.ftruncate可以
    Sherlockhlt
        15
    Sherlockhlt  
    OP
       2012-11-05 16:54:11 +08:00
    感谢各位的回复,我程序已经写好了,最后总结下:
    觉得还是3楼的办法比较pythonic,因为无论如何都平均要把半个文件进行IO处理,所以
    直接把这个文件进行处理,这样代码比较好读,而且代价其实并不是太大(平均多1倍IO)
    如果文件真的很大,就不应该用纯文本了,应该用数据库来处理才是。
    Sherlockhlt
        16
    Sherlockhlt  
    OP
       2012-11-05 17:10:36 +08:00
    @013231
    前面说错了,write不行的,看来还是要用mmap
    timonwong
        17
    timonwong  
       2012-11-05 17:27:09 +08:00
    @Sherlockhlt
    如果只是一行的话, mmap实现很直接,找到那一行,然后把后面的内容通过memmove移动上前并覆盖就可以了,如果文件过大,可能还要拆分执行,不过一般几个G还是没问题(32位python除外)。
    BOYPT
        18
    BOYPT  
       2012-11-06 09:29:27 +08:00
    os.system('sed -i 1001d %s' % filename)
    Sherlockhlt
        19
    Sherlockhlt  
    OP
       2012-11-06 10:00:32 +08:00
    @BOYPT
    用sed缺少可移植性吧
    BOYPT
        20
    BOYPT  
       2012-11-06 10:08:59 +08:00   1
    @Sherlockhlt 移植性这么虚幻的东西我一般不考虑。
    BOYPT
        21
    BOYPT  
       2012-11-06 10:18:25 +08:00
    更科学应该使用sh模块: https://github.com/amoffat/sh
    yeyu1989
        22
    yeyu1989  
       2017-09-20 14:15:34 +08:00
    这么多年过去了,这个问题有没有好的解决办法了呢
    tqz
        23
    tqz  
       2020-07-23 15:38:29 +08:00
    这么多年过去了,这个问题有没有好的解决办法了呢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5808 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 06:15 PVG 14:15 LAX 23:15 JFK 02:15
    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