python - 如何使用 Python 有效地读取带有自定义换行符的大文件?
问题描述
我们有一个巨大的.csv
文件,但它似乎并不是真正的 csv。
行尾是\tl\n
.
此换行符之间的文本有时具有“真正的”换行符。我们不想在这些问题上分裂。
我们目前使用awk
.
awk_code = r'BEGIN{ RS="""(\tl\n)"""; FS="\t"} { print "\42"$1"\42,\42"$2"\42,\42\42\42"$3"\42\42\42,\n";}'
bash_command_awk = f"awk '{awk_code}' {input_file_path} > {output_path}"
awk_command_output = subprocess.check_output(bash_command_awk,stderr=subprocess.STDOUT, shell=True)
我正在尝试找到一种直接在 Python 中执行此操作的有效方法,并尝试将自定义换行符传递给.open()
命令。
def process_without_putting_file_in_RAM(file_to_process):
with file_to_process.open(encoding="utf-8", newline="\tl\n") as csv_file:
for line in csv.reader(csv_file):
但是,我很快了解到换行 arg 只接受一个默认字符。
如何有效地处理这个包含奇怪行尾的文件?
解决方案
这是一个可以正确处理块之间的多字符换行符的函数
def line_splitter(file, newline, chunk_size=4096):
tail = ''
while True:
chunk = file.read(chunk_size)
if not chunk:
if tail:
yield tail
break
lines = (tail + chunk).split(newline)
tail = lines.pop(0)
if lines:
yield tail
tail = lines.pop()
yield from lines
另一个版本,虽然它不会复制整个块并没有证明更快。对于大块,它会稍微快一些。不要使用小于换行大小的 chunk_size :)
def line_splitter(file, newline, chunk_size=4096):
tail = ''
while True:
chunk = file.read(chunk_size)
if not chunk:
if tail:
yield tail
break
lines = chunk.split(newline)
tail = (tail + lines[0]).split(newline)
if len(tail) > 1:
lines[0] = tail[1]
else:
del lines[0]
tail = tail[0]
if lines:
yield tail
tail = lines.pop()
yield from lines
调用者应该是这样的:
with longabstract_file.open() as f:
for line in line_splitter(f, "\tl\n"):
if line: # ignore blank lines
print(line)
推荐阅读
- c# - 美化控制台窗口?
- html - html/css 在 ios 设备上没有响应
- python - 如果使用打印,计算结果显示不同
- python - pip3 install PyQt5 --user 失败
- r - 在 R 中,如何计算特定列的出现次数?
- audio - 如何使用 FFmpeg (C/C++) 将原始 pcm_f32le 音频编码为 AAC 编码音频?
- arrays - 获取覆盖循环数组中所有有效条目的最小子数组
- graphql - 如何使用变量进行 Hasura 查询?
- python - 添加约束后 Scipy 差分进化失败
- python-3.x - 获取输入并将每个字符乘以列表中包含的内容