我有一个多 GB 的文本文件,我想用 替换utf8mb4_0900_ai_ci
其中的所有utf8mb4_unicode_520_ci
。
通常,我会sed -i
按照这里的建议使用它:使用 SED 在文件中查找并替换字符串,而不使用临时文件
但是,这会在后台创建一个临时文件,而我需要在没有磁盘空间支持该操作的环境中进行此替换。
我如何才能就地修改文件?
我有一个多 GB 的文本文件,我想用 替换utf8mb4_0900_ai_ci
其中的所有utf8mb4_unicode_520_ci
。
通常,我会sed -i
按照这里的建议使用它:使用 SED 在文件中查找并替换字符串,而不使用临时文件
但是,这会在后台创建一个临时文件,而我需要在没有磁盘空间支持该操作的环境中进行此替换。
我如何才能就地修改文件?
只是为了好玩,我尝试了一个就地替换 bash 脚本,
myreplace
。显然,在未先保存原始数据并进行大量测试的情况下,请勿使用此脚本。它可能会对超过 4G 字节的文件产生问题,因为数字超过 32 位。此外,如果有数百万个匹配项,tac
将耗尽内存或临时文件空间。我还必须编写一个小的 perl 脚本来执行seek(2)
,但肯定已经有一个了。原理是使用
grep
找到匹配的字节偏移量,然后使用tac
反转此列表,以便我们从末尾开始。我们在文件上打开 2 个文件描述符。fdr
将是我们当前的读取位置和fdw
写入位置。它们都从文件末尾开始,但位于新的名义末尾,该末尾fdw
比 更远 ,即替换字符串的长度差为 倍。nummatches
len3
我们使用函数
domove
在读取器上回溯一个数量,在写入器上回溯相同的数量,读取并将该数量复制到写入器。然后我们需要再次回溯到我们的新位置。我们在读取器中回溯以跳过旧字符串。在写入器中我们回溯,写入替换字符串,然后回溯覆盖它。
我创建了一个演示文件来测试(
str1
来自脚本):我的 perl 有点生疏了,但是这里是 perl 脚本“seek”: