我们有一个庞大的@effect()
add$ = this.actions$
.ofType<Add>(ADD)
.pipe(mergeMap(a =>
this.sharedService.add(a.entity, a.api)
.pipe(map(s => new AddResult(Ok(s.id))))
.pipe(catchError(e => of(new AddResult(Err(e)))))));
文件,但它似乎并不是真的csv。
行尾为.csv
。
此换行符之间的文本有时具有“真实”换行符。我们不想在这些问题上分开。
我们目前使用\tl\n
进行操作。
awk
我试图找到一种直接在Python中执行此操作的有效方法,并尝试将自定义换行符传递到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)
命令中。
.open()
但是,我很快了解到换行arg仅接受默认字符之一。
如何有效处理包含奇怪行尾的文件?
答案 0 :(得分:1)
这是一个可以正确处理块之间的多字符换行符的功能
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)
答案 1 :(得分:0)
假设您的csv是用逗号或空格分隔,而不是制表符,那么您要查找的是lineterminator
flag,但由于自动假定'\n'
是一个换行符,因此不需要这样做。来自文档:
注意:阅读器经过硬编码,可以将
'\r'
或'\n'
识别为 行尾,并忽略lineterminator
。这种行为可能会改变 未来。
所以您可以做的是添加字符串方法.replace()
来摆脱'\tl'
这样的情况
def process_without_putting_file_in_RAM(file_to_process):
with file_to_process.open(encoding="utf-8") as csv_file:
for line in csv.reader(csv_file, delimiter=","):
print(line[-1].replace('\tl', ''))
答案 2 :(得分:-1)
为什么不使用pandas
。具体来说,pandas.read_csv
使用lineterminator
和chunksize
参数:
import pandas as pd
batch_size = 10000
new_line_str = '\tl\n'
iterator_df = pd.read_csv(file_to_process, chunksize=batch_size, lineterminator=new_line_str)
for chunk in iterator_df:
# process chunk here