使用python修改文件内容

一、概述

大家都知道linux的一些命令例如sed、awk可以实现对文件内容的修改,那么python能否实现类似的功能,最近刚好工作上有处理文件内容的需求,所以研究了一下python在处理文件内容方面的功能。

 

二、在指定的关键字前/后插入内容

在指定的关键字前/后插入内容是一个比较常见的需求,我们先来看下在关键字之前插入内容怎么实现。

有时候我们做一些复杂的功能,碰到有些逻辑想不明白的时候,可以把环境简化一些,用最简单的demo来帮助自己理解,还是比较有效的。

先看简单的例子。

基于 [在数字6前面插入数字5] 这样的需求,写了以下一段代码。

def add_content_before_keyword():
    tmp = '1234678'
    index = tmp.find('6')
    print('数字6在字符串tmp中的位置是:{}'.format(str(index)))
    add_num = '5'
    part_ahead = tmp[:index]
    # 因为Python的切片包含起始索引本身的值,例如list[5:10]的切片中是包含list[5]本身的值的,所以这里直接使用[index:]即可
    part_behind = tmp[index:]
    print('字符串前半部分切片的值是:{}'.format(str(part_ahead)))
    print('字符串后半部分切片的值是:{}'.format(str(part_behind)))
    tmp_modified = part_ahead + add_num + part_behind
    print('插入数字5之后,新的字符串为:{}'.format(tmp_modified))
add_content_before_keyword()

运行结果:

数字6在字符串tmp中的位置是:4
字符串前半部分切片的值是:1234
字符串后半部分切片的值是:678
插入数字5之后,新的字符串为:12345678

Process finished with exit code 0

在这个例子中,总体上看一共做了三件事:

1.获取关键字的下标(我们要在某个关键字前/后插入内容,那肯定需要根据自己的需求场景确定一个关键字,这里关键字是6)

2.将待处理的文本内容(1234678)通过第一步获取的关键字下标,进行切片,分割成两个部分

3.将数字5和第二步切片得到的文本重新组成一个新的字符串(12345678)

 

 

那么再来看一下在关键字后面加入指定的内容,例如下面这个例子:

需求:在数字5之后插入数字6

def add_content_after_keyword():
    tmp = '1234578'
    index = tmp.find('5')
    print('数字5在字符串tmp中的位置是:{}'.format(str(index)))
    add_num = '6'
    # Python的切片是不包含 终止索引 本身的值,例如list[0:7]不包含list[7]本身的值,所以这里要加上len(add_num),增加终止索引的下标
    part_ahead = tmp[:index+len(add_num)]
    # Python的切片包含 起始索引 本身的值,例如list[0:10]是包含list[0]本身的值的,而我们这里的目标是获取字符串关键字之后的部分,索引需要加上len(add_num)以避免切片的内容包含关键字本身
    part_behind = tmp[index+len(add_num):]
    print('字符串前半部分切片的值是:{}'.format(str(part_ahead)))
    print('字符串后半部分切片的值是:{}'.format(str(part_behind)))
    tmp_modified = part_ahead + add_num + part_behind
    print('插入数字6之后,新的字符串为:{}'.format(tmp_modified))

add_content_after_keyword()

这里需要关注一下注释,注释说明了part_ahead 和 part_behind的索引为什么需要加上len(add_num)

运行结果:

数字5在字符串tmp中的位置是:4
字符串前半部分切片的值是:12345
字符串后半部分切片的值是:78
插入数字6之后,新的字符串为:12345678

Process finished with exit code 0

 

那么对于复杂的处理场景也是一样的,我们以修改nginx的配置文件举例说明:

需求:

在nginx.conf的server块中加入一段配置,使得用户能通过nginx来访问静态资源

待处理的nginx.conf文件内容:

user root;
worker_processes 2;
worker_rlimit_nofile 2048;
events {
        use epoll;
        worker_connections 1024;
        }
http {
        include mime.types;
        access_log  /opt/logs/nginx/access.log  main;
        gzip on;
        gzip_min_length  1k;
        gzip_buffers 4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 9;
        gzip_types text/plain application/x-javascript text/css application/xml;
        gzip_vary on;
    server {
        listen       8081;
        server_name localhost;
        charset utf-8;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    server {
        listen       8082;
        server_name localhost;
        charset utf-8;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    include /opt/nginx/conf.d/*.conf;
}

 

需要添加的配置:

        location ^~ /static {
                root /opt/application/;
                index index.htm index.html;
                try_files $uri $uri/ /static/index.html;
        }

首先我们需要确定一个关键字,就是在nginx.conf中的哪个关键字之后加入我们需要的配置,这里我们将关键字选定为nginx.conf中的“charset utf-8;”

这个示例中展示了有多个关键字的情况,特意加了8081和8082两个server块。

代码:

import re
def add_nginx_conf(file_path):
    with open(file_path, 'r') as r:
        # 定义匹配关键字,注意这里如果有正则里面的需要转义的字符,要做对应的转义
        keyword_matching = '        charset utf-8;'
        content = r.read()
        # 这里考虑了需要匹配多个相同的关键字,并且插入多段配置的情况,这行代码的作用是获取待处理的文本中有几处这样的关键字
        keyword_rate = len([m.start() for m in re.finditer(keyword_matching, content)])
        # 定义准备添加的文本
        add_line = """        location ^~ /static {
        \n            root /opt/application/;
        \n            index index.htm index.html;
        \n            try_files $uri $uri/ /static/index.html;
        \n        }\n"""
        for i in range(keyword_rate):
            # 获取匹配到的关键字对应的索引值
            index = [m.start() for m in re.finditer(keyword_matching, content)][i]
            # 在每一处匹配到的关键字下方插入相关的配置。
            content = content[:index] + add_line + content[index:]
            with open(file_path, 'w') as w:
                w.write(content)
add_nginx_conf('/opt/tmp/nginx.conf')

代码运行之后nginx.conf的内容;

user root;
worker_processes 2;
worker_rlimit_nofile 2048;
events {
        use epoll;
        worker_connections 1024;
        }
http {
        include mime.types;
        access_log  /opt/logs/nginx/access.log  main;
        gzip on;
        gzip_min_length  1k;
        gzip_buffers 4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 9;
        gzip_types text/plain application/x-javascript text/css application/xml;
        gzip_vary on;
    server {
        listen       8081;
        server_name localhost;
        location ^~ /static {

            root /opt/application/;

            index index.htm index.html;

            try_files $uri $uri/ /static/index.html;

        }
        charset utf-8;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    server {
        listen       8082;
        server_name localhost;
        location ^~ /static {

            root /opt/application/;

            index index.htm index.html;

            try_files $uri $uri/ /static/index.html;

        }
        charset utf-8;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    include /opt/nginx/conf.d/*.conf;
}

三、删除文件中指定的内容

删除文件中指定的内容同样可以通过切片来实现,但是实际操作中并不建议采取切片的方式,原因是只有在精确匹配待删除内容的情况下,通过切片操作才能正确实现删除需求。

而如果待删除内容中有大量正则表达式时,匹配工作就变得复杂且容易出错。

这里我们来介绍一下除了切片以外的方法:

先看一个简单的例子:

 

未完待续

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值