如何在Unix中替换40GB文件中的两个字符?



我有两个巨大的json文件(每个20GB),我需要加入他们。文件的内容如下:

file_1.json = [{"key": "value"}, {...}]
file_2.json = [{"key": "value"}, {...}]
然而,主要的问题是,我需要所有的字典都在同一个列表中。我试图在python中这样做,但不幸的是,我没有足够的内存来做这个操作。

所以,我想也许我可以用unix命令来解决这个问题,通过替换,在第一个文件中,,](注意,逗号后面有一个空格),并从第二个文件中删除[。然后,我将使用catunix命令连接这两个文件。

是否有一种方法让我在unix中只编辑最后10个字符?

我试图使用echotr,但我可能在语法上做错了。

你可以很容易地添加到文件的地方,即在末尾添加字符,而不重写已经存在的数据。使用正确的工具(如果系统有truncate),您可以就地截断文件,即删除末尾的字符而不重写保留的数据。使用合适的工具(dd,如果您想冒险的话),您可以用相同长度的字符串替换文件的一部分,而无需重写未更改的部分。另一方面,在不重写文件的情况下,你不能从文件的开头或中间删除字符(除了一些与此无关的例外情况)。

但是无论如何,就地重写这两个文件对你没有多大帮助。您至少需要重写第二个文件的内容,以便将其附加到第一个文件。

如果不需要保留分割文件,可以在处理好中间的标点符号后,将第二个文件附加到第一个文件的位置。从第一个文件中删除最后一个]字符,以及后面的空格和换行符。假设第一个文件以]和换行符结尾,并且您有GNU核心实用程序(例如非嵌入式Linux):

truncate -s -2 file_1.json

现在您可以在第一个文件中添加逗号和可选的换行符,并附加第二个文件中的数据,但不包含第一个字符。

echo , >>file_1.json
tail -c +2 file_2.json >>file_1.json

如果您想保持原始文件不被修改,您可以复制第一个文件并截断它。或者您可以直接创建第一个文件的截断副本(仍然假设是GNU coretils):

head -c -2 file_1.json >concatenated.json
echo , >>concatenated.json
tail -c +2 file_2.json >>concatenated.json

如果你更熟悉Python,你可以在Python中完成所有这些。只是不要一次读取整个文件,即不要调用read()或使用readline()以一次读取所有行的方式。相反,每次读取和处理单行(如果行很短)或单个数据块。未测试的代码:

with open('concatenated.json', 'wb') as out:
with open('file_1.json', 'rb') as inp:
buf = bytes(1024)
size = inp.seek(-len(buf), io.SEEK_END)
n = inp.readinto(buf)
m = re.search(rb']s*Z', buf)
stop_at = m.start()
inp.seek(0, io.SEEK_SET)
n = inp.readinto(buf)
total = n
while n > 0:
out.write(buf)
n = inp.readinto(buf)
total += n
if total > stop_at:
out.write(buf[:len(buf)-(total-stop_at)])
n = 0
out.write(b',')
with open('file_2.json', 'rb') as inp:
buf = bytes(1024)
n = inp.readinto(buf)
assert buf[0] == b'['
buf[0:1] = b'n'
while n > 0:
out.write(buf)
n = inp.readinto(buf)

最新更新