首页
Search
1
v2ray异常错误之二
3,310 阅读
2
linux时区设置
2,698 阅读
3
DB2常用操作
2,173 阅读
4
websphere修改jvm内存xmx和xms
1,929 阅读
5
nfs客户端文件属主为nobody的现象
1,552 阅读
技术
生活
运动
游戏
电影
登录
Search
标签搜索
docker
linux
troubleshooting
nginx
secure
truenas
mysql
windows
python
esxi
docker swarm
oracle
zabbix
tomcat
blog
dsm
群晖
rpa
freenas
db
yuc
累计撰写
291
篇文章
累计收到
0
条评论
首页
栏目
技术
生活
运动
游戏
电影
页面
搜索到
1
篇与
的结果
2024-08-28
超大文件的修改编辑方法
背景 想象一个场景,假如有一个导出的数据库纯文本文件需要更改其中一两行的内容,有什么快速有效的办法? 服务器配置好的情况下: 当文本内容是十几G的时候,我们可以考虑使用 vim 来修改,无非是定位行,搜索关键字,更改后保存慢一些 当文本内容是几十G的时候,我们可以考虑使用 sed 等命令搜索更改文本内容,这时候保存是非常慢的,vim几乎处理不了了,并且这些命令会全量的生成临时文件,需要两倍的文件空间,最后替换才能保存成功 那么就没有好办法,能够直接修改文件的部分内容,而不需要这么长时间吗,就算仅修改文件起始行的某个字符这样的简单需求 方案 反向推理,我们需要一个手段能截断文件的内容,让需要修改的部分不要那么大,在修改完成后再合并这些内容即可 方案1 最开始我想到的是 split,它能够切割文件,并且它切割的速度是非常快的,假如有一个 270G 的文件需要修改,那么我可以切割成每个文件为 40G 甚至 20G ,在某个文件中修改完指定内容后合并所有文件即可。这里面花费的时间主要有几个: 按照每个子文件大小为 20G 切割一个 270G 的文件 (这部分也比较慢,raidz3机械400M左右读写需一个小时) 找到需要修改的内容,如果内容比较靠前或者靠后那么基本是第一或者最后一个文件 修改文件,文件只有20G了,那么修改的速度是可以接收的 合并文件 (这部分的时间也比较慢,大概670秒) 方案2 上面方案中切割文件虽然从理论上比直接修改原文件更好,比如不需要生成全量临时文件,修改的时候只改一部分,时间和操作可控(相对于直接修改270G文件时间是未知数)。但它仍然是有很大的缺陷 它仍然需要修改数十G的文件,并且切割和合并慢,总之就是需要操作的还是文件太大 那么有没有方法能够把文件的一部分切割出来,修改之后再替换呢? 这样似乎就规避了所有的缺点,答案是有的,我们可以使用 dd 来实现。大致的思路如下: 首先我们把文件需要修改的一部分切割下来,这里可以使用 dd or head or tail,这部分的重点是 最好能够截断到某一完整的行,所以多几行也是没关系的,原因后面会介绍,然后记录文件的字符数wc -c 接下来修改截断的这部分内容,就算截取了几万行,几十万行,甚至上百万行,这个速度仍然是很快的 重点: 修改之前查看文本最后是否存在换行符,如果没有 vim 需要设置 binary, noendofline 这样vim不会自动添加,否则vim会自动添加一个换行符,导致文件格式出现问题 接下来调整文件的字节数,保证修改后的文件与截断之前的文件字节数一致,使用 wc -c 确认,如果长度变了,覆盖文本的时候会有问题,举例:原文本是26个字母,然后截取前8个修改内容,但是修改后长度变成了16,那么会覆盖这16个字母到源26个字母中,中间不想被修改的部分也被覆盖了,所以这里重点注意 在覆盖文件后,查看处理后的文件,有两个地方要检查,分别是:修改的地方是否成功,覆盖的末尾处是否存在截断或者内容不匹配等 实际操作: 使用 dd or head or tail 取文件需要修改的附近处,dd 设置 bs=1 大概率不是完整的行,需要设置 vim binary, noendofline , 而 head, tail 一般都是完整的行,可以不需要设置 查看文件的字符数,wc -c 修改文件内容,使用你喜欢的方式即可 查看新字符数是否跟之前一致,少了则补,多了则删 覆盖新文本到原文本 dd if=temp.txt of=access.txt conv=notrunc,最重要的是后面这个参数,一般使用 dd 会把文件覆盖成新文本,就是新文本内容比原文本短的话,多余的会被截断,相当于只会保留新文本,使用这个参数后会保持原文本后面的内容不动
2024年08月28日
6 阅读
0 评论
0 点赞