Python 删去“;“字符串”;使用正则表达式包含CSV文件的最后一行
我是Python新手。我有数千个CSV文件,其中有一组文本在数字数据记录之后出现,我想删除所有以文本开头的行。例如:Python 删去“;“字符串”;使用正则表达式包含CSV文件的最后一行,python,csv,Python,Csv,我是Python新手。我有数千个CSV文件,其中有一组文本在数字数据记录之后出现,我想删除所有以文本开头的行。例如: col 1 col 2 col 3 -------------------- 10 20 30 -------------------- 45 34 56 -------------------- Start 8837sec 9items -------------------- Total 6342sec
col 1 col 2 col 3
--------------------
10 20 30
--------------------
45 34 56
--------------------
Start 8837sec 9items
--------------------
Total 6342sec 755items
好的是,所有csv文件的文本都以第1列中的“开始”开头。我更愿意删除所有行,包括显示“开始”的行
以下是我到目前为止的情况:
import csv, os, re, sys
fileList = []
pattern = [r"\b(Start).*", r"\b(Total).*"]
for file in files:
fullname = os.path.join(cwd, file)
if not os.path.isdir(fullname) and not os.path.islink(fullname):
fileList.append(fullname)
for file in fileList:
try:
ifile = open(file, "r")
except IOError:
sys.stderr.write("File %s not found! Please check the filename." %(file))
sys.exit()
else:
with ifile:
reader = csv.reader(ifile)
writer = csv.writer(ifile)
rowList = []
for row in reader:
rowList.append((", ".join(row)))
for pattern in word_pattern:
if not (re.match(pattern, rowList)
writer.writerow(elem)
运行此脚本后,它会给我一个空白的csv文件。知道要更改什么吗?您不需要CSV阅读器。您可以简单地找到偏移量并截断文件。以二进制模式打开文件,使用多行正则表达式在文本中查找模式并使用其索引
import os
import re
# multiline, ascii only regex matches Start or Total at start of line
start_tag_finder = re.compile(rb'(?am)\nStart|\nTotal').search
for filename in files: # TODO: I'm not sure where "files" comes from...
# NOTE: no need to join cwd, relative paths do that automatically
if not os.path.isdir(filename) and not os.path.islink(filename):
with open(filename, 'rb+') as f:
# NOTE: you can cap file size if you'd like
if os.stat(filename).st_size > 1000000:
print(filename, "overflowed 10M size limit")
continue
search = start_tag_finder(f.read())
if search:
f.truncate(search.start())
在您整理好文件列表后,我会尝试以下方法:
for file in fileList:
keepRows = []
open(file, 'r') as oFile:
for row in oFile:
if row[0] != "Start":
keepRows += row
else:
oFile.close()
with open(file, 'wb+') as nFile:
writer = csv.writer(nFile, delimiter=',')
writer.writerow([keepRows])
这将打开原始文件,获取所需的行,关闭它并使用w+
打开它。这将覆盖文件,保留名称,但通过truncate将其清除,然后将在清除的文件的每一行上写入要保留的每一行
或者,您可以为每个csv创建一个新文件,具体操作如下:
for file in fileList:
keepRows = []
with open(file, 'r') as oFile, open('new_file.csv', 'a') as nFile:
for row in oFile:
if row[0] != "Start":
keepRows += row
else:
oFile.close()
for row in keepRows:
nFile.write(row)
使用a
打开时,每次都会将光标放在下一行,因为这是append
。用户面前的.writerow
方法是iterables,这就是为什么它在[]
中用于对象
,其中作为中的每个组或行
,而在追加
中不需要iterables,并将分组中的每个项写入自己的列,移动到下一行并执行相同的操作
编辑:更新了二进制文件模式
和.writer()的语法
本例中没有名为writer
的变量。你应该得到一个例外,什么也没写。您只想在开始后剥离所有内容
?你不需要csv。csv的编码是什么?是ASCII还是UTF-8?我在代码中添加了writer语句。CSV文件的编码是ASCII格式。您好,谢谢,它可以工作:)。一个简单的问题:string:(string.startswith(keywords))的方法在这些情况下也能工作吗,我的关键字是keywords=(“Search”,“Total”)?这个例子在一个块中处理文件,而不是逐行处理,因此startswith
不起作用,但是f.read()中的“\nStart”会起作用。正则表达式允许您在单个C扩展块中一次检查多个关键字,我认为这样更快。在大多数现代计算机上,烧掉几兆内存来读取一个文件是很简单的,这(一个猜测!)应该有很好的性能。您可以逐行阅读,也可以使用启动。您好,谢谢您的帮助。我理解你的第一个创建新列表的方法,即在“开始”之后隔离任何内容。但是,当您开始覆盖文件并保留名称时,我看不到truncate选项。另外,我认为csv.writer()应该以“nfile”作为参数?@Salil Nanda,我更新了.writer()
这篇文章,因为你是正确的,我忘了给它提供一个file对象。truncate选项基于调用open()
函数的模式。使用w
表示write
使用b
表示文件以二进制
模式打开,使用+
启用读写
更新功能。默认情况下,w+
将文件覆盖为0字节(即截断文件)。这就是为什么我们在收集完所需行后调用wb+
模式。我们使用b
的原因是,Windows操作系统可以解释文件的新行
方面。@Salil Nandra,响应太长。以下是有关open()
modes:1)的一些参考资料。2) 非常感谢你的帮助。我会调查的。