我有一个Python脚本修改CSV文件以将文件名添加为最后一列:
import sys
import glob
for filename in glob.glob(sys.argv[1]):
file = open(filename)
data = [line.rstrip() + "," + filename for line in file]
file.close()
file = open(filename, "w")
file.write("\n".join(data))
file.close()
Run Code Online (Sandbox Code Playgroud)
不幸的是,它还将文件名添加到文件的标题(第一行).我希望将字符串"ID"添加到标题中.谁能建议我怎么做?
以下是您当前代码的一些小注释:
file
作为变量名称是一个坏主意,因为它会影响内置类型.with
语法自动关闭文件对象.Filename
,而不是仅仅省略第一行中的列吗?最后的考虑将使我csv
倾向于使用模块,它将处理引用和取消引用.例如,您可以尝试类似以下代码:
import glob
import csv
import sys
for filename in glob.glob(sys.argv[1]):
data = []
with open(filename) as finput:
for i, row in enumerate(csv.reader(finput)):
to_append = "Filename" if i == 0 else filename
data.append(row+[to_append])
with open(filename,'wb') as foutput:
writer = csv.writer(foutput)
for row in data:
writer.writerow(row)
Run Code Online (Sandbox Code Playgroud)
这可能会引用数据与输入文件略有不同,因此您可能希望使用csv模块的文档中的引用选项csv.reader
和csv.writer
描述.
另外一点,您可能有充分的理由将glob作为参数而不仅仅是命令行中的文件,但这有点令人惊讶 - 您必须调用脚本./whatever.py '*.csv'
而不仅仅是./whatever.py *.csv
.相反,你可以这样做:
for filename in sys.argv[1:]:
Run Code Online (Sandbox Code Playgroud)
...在脚本知道任何事情之前让shell扩展你的glob.
最后一件事 - 你正在采取的当前方法有点危险,因为如果在写回同一文件名时出现任何问题,你将丢失数据.避免这种情况的标准方法是改为写入临时文件,如果成功,则将临时文件重命名为原始文件.所以,你可能会把整个事情重写为:
import csv
import sys
import tempfile
import shutil
for filename in sys.argv[1:]:
tmp = tempfile.NamedTemporaryFile(delete=False)
with open(filename) as finput:
with open(tmp.name,'wb') as ftmp:
writer = csv.writer(ftmp)
for i, row in enumerate(csv.reader(finput)):
to_append = "Filename" if i == 0 else filename
writer.writerow(row+[to_append])
shutil.move(tmp.name,filename)
Run Code Online (Sandbox Code Playgroud)