首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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
V2EX  ›  Python

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

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

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

    不如加一些标记作为作废一行的指示符。
        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)
        4
    Sherlockhlt   2012-11-05 16:07:40 +08:00
    @timonwong
    能说具体点吗?
        5
    Sherlockhlt   2012-11-05 16:08:47 +08:00
    @phuslu
    这个方法我也想过,不过还是有绕个大湾的感觉
        6
    Sherlockhlt   2012-11-05 16:09:41 +08:00
    @zenomac
    增加表示删除了没的这个标记后如何修改这个标记呢?
        7
    hyq   2012-11-05 16:15:06 +08:00
    @Sherlockhlt 首先得定位到那一行行首在文件中的偏移地址a,然后需要判断这行的长度l,然后需要把a+l后的所有文本全部都向前移动l个字节.
    文本存储的时候不是链表结构的,我觉得在处理纯文本上已经没有更快的方法了
        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
        9
    imom0   2012-11-05 16:28:23 +08:00
        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 那是我問的...
        11
    clowwindy   2012-11-05 16:36:29 +08:00
    @phuslu 这个方法还可以改进一下,从跳过的行开始以 4K 为单位挪动后面的内容,而不是以行为单位。
        12
    Sherlockhlt   2012-11-05 16:49:53 +08:00
    @hyq
    试了下,最后要怎么改变文件大小呢?
        13
    Sherlockhlt   2012-11-05 16:50:31 +08:00
    @013231
    改成废弃一行其实直接fp.write()就可以了
        14
    hyq   2012-11-05 16:53:15 +08:00
    @Sherlockhlt os.ftruncate可以
        15
    Sherlockhlt   2012-11-05 16:54:11 +08:00
    感谢各位的回复,我程序已经写好了,最后总结下:
    觉得还是3楼的办法比较pythonic,因为无论如何都平均要把半个文件进行IO处理,所以
    直接把这个文件进行处理,这样代码比较好读,而且代价其实并不是太大(平均多1倍IO)
    如果文件真的很大,就不应该用纯文本了,应该用数据库来处理才是。
        16
    Sherlockhlt   2012-11-05 17:10:36 +08:00
    @013231
    前面说错了,write不行的,看来还是要用mmap
        17
    timonwong   2012-11-05 17:27:09 +08:00
    @Sherlockhlt
    如果只是一行的话, mmap实现很直接,找到那一行,然后把后面的内容通过memmove移动上前并覆盖就可以了,如果文件过大,可能还要拆分执行,不过一般几个G还是没问题(32位python除外)。
        18
    BOYPT   2012-11-06 09:29:27 +08:00
    os.system('sed -i 1001d %s' % filename)
        19
    Sherlockhlt   2012-11-06 10:00:32 +08:00
    @BOYPT
    用sed缺少可移植性吧
        20
    BOYPT   2012-11-06 10:08:59 +08:00   ♥ 1
    @Sherlockhlt 移植性这么虚幻的东西我一般不考虑。
        21
    BOYPT   2012-11-06 10:18:25 +08:00
    更科学应该使用sh模块: https://github.com/amoffat/sh
        22
    yeyu1989   2017-09-20 14:15:34 +08:00
    这么多年过去了,这个问题有没有好的解决办法了呢
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2317 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 22ms · UTC 09:05 · PVG 17:05 · LAX 02:05 · JFK 05:05
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1