添加文件名作为CSV文件的最后一列

时间:2011-04-18 08:29:14

标签: python linux csv

我有一个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()

不幸的是,它还将文件名添加到文件的标题(第一行)。我希望将字符串“ID”添加到标题中。谁能建议我怎么做呢?

6 个答案:

答案 0 :(得分:6)

查看官方csv module

答案 1 :(得分:5)

以下是您当前代码的一些小注释:

  • 使用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)

这可能会引用与输入文件略有不同的数据,因此您可能希望使用csv.readercsv.writer in the documentation for the csv module所述的引用选项。

另外一点,您可能有充分的理由将glob作为参数而不仅仅是命令行中的文件,但这有点令人惊讶 - 您必须将脚本称为./whatever.py '*.csv'而不只是./whatever.py *.csv。相反,你可以这样做:

for filename in sys.argv[1:]:

...让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)

答案 2 :(得分:1)

您可以尝试:

data = [file.readline().rstrip() + ",id"]
data += [line.rstrip() + "," + filename for line in file]

答案 3 :(得分:1)

使用Python附带的CSV module

import csv
import sys

def process_file(filename):
    # Read the contents of the file into a list of lines.
    f = open(filename, 'r')
    contents = f.readlines()
    f.close()

    # Use a CSV reader to parse the contents.
    reader = csv.reader(contents)

    # Open the output and create a CSV writer for it.
    f = open(filename, 'wb')
    writer = csv.writer(f)

    # Process the header.
    header = reader.next()
    header.append('ID')
    writer.writerow(header)

    # Process each row of the body.
    for row in reader:
        row.append(filename)
        writer.writerow(row)

    # Close the file and we're done.
    f.close()

# Run the function on all command-line arguments. Note that this does no
# checking for things such as file existence or permissions.
map(process_file, sys.argv[1:])

您可以按如下方式运行:

blair@blair-eeepc:~$ python csv_add_filename.py file1.csv file2.csv

答案 4 :(得分:1)

您可以尝试更改代码,但建议使用csv module。这应该给你想要的结果:

import sys
import glob
import csv

filename = glob.glob(sys.argv[1])[0]
yourfile = csv.reader(open(filename, 'rw'))

csv_output=[]

for row in yourfile:
    if len(csv_output) != 0:     # skip the header
        row.append(filename)
    csv_output.append(row)

yourfile = csv.writer(open(filename,'w'),delimiter=',')
yourfile.writerows(csv_output)

答案 5 :(得分:1)

您可以使用fileinput进行就地编辑

import sys
import glob
import fileinput

for filename in glob.glob(sys.argv[1]):
    for line in fileinput.FileInput(filename,inplace=1) :
       if fileinput.lineno()==1:
          print line.rstrip() + " ID"
       else
          print line.rstrip() + "," + filename