将更改应用于同一目录中的多个文件

时间:2014-07-22 16:11:27

标签: python loops csv

我有一个包含多个扩展名的文件的目录,但我只对使用特定扩展名感兴趣。

  • document.doc
  • file_with_the.extensionwanted
  • other_file.extensionwanted
  • presentation.ppt
  • sheet.xls
  • whatever.extensionwanted

我想使用的文件是csv样式,如下所示:

This is a sentence, Info 1, Info 2, Info 3,...
This is a number: 37, Info 1, Info 2, Info 3,...
This is a letter:  r, Info 2, Info 3,...
This is a symbol:  $, Info 1, Info 2, Info 3,...
Here theres 'mb' too, Info 1, Info 2, Info 3,...

我想运行一个脚本,删除每个以.extensionwanted结尾的文件中的每一行,该文件包含第一列中的两个不同的字符串,并将结果放在具有相同扩展名的文件中,以避免空行(我不知道'只要他们保持扩展名,就会有不同的名称。

例如,如果我想要删除包含字符串的行' '和' mb '同时在第1列中,想要的结果是:

This is a sentence, Info 1, Info 2, Info 3,...
This is a letter:  r, Info 2, Info 3,...
Here theres 'mb' too, Info 1, Info 2, Info 3,...

我知道如何使用具有给定扩展名的单个文件来执行此操作。例如,对于.csv:

import csv
import os

col = 0
look_for1 = set(['This'])
look_for2 = set(['mb'])

# Writing info wanted
with open('./Directory/file.csv','rb') as inf, \
        open('./Directory/other_file.csv','wb') as outf:
    incsv = csv.reader(inf, delimiter=',')
    outcsv = csv.writer(outf, delimiter=',')
    outcsv.writerows(row for row in incsv if look_for1 in row[col] and
                                                look_for2 in[col])

os.remove('./Directory/file.csv')

以及如何列出

import glob
files = glob.glob("*.extensionwanted")
for filename in files
    print filename

但是在这种情况下,扩展名不是.csv,我想循环遍历该扩展名的文件夹中的所有文件。 我在动态环境中执行此操作而不是使用静态文件名有点丢失。有人可以帮我一把吗?

3 个答案:

答案 0 :(得分:1)

您可能想要使用os.path.splitext功能。它允许您从您的文件中提取扩展名,允许您编写如下过滤器:

extensions = set(['.csv', '.bob', '.txt'])
files = os.listdir(dirname)

target_files = [x for x in files if os.path.splitext(x)[1] in extensions]

然后,您可以循环浏览target_files中的文件。

答案 1 :(得分:1)

因此,根据您发布的代码,您似乎已经找到了如何迭代指定扩展名的文件名对特定文件进行操作。我可能会过度使用这个,但你不能只是将两者粉碎在一起来对文件的迭代进行操作吗?它可能看起来像

import csv
import os
import glob

col = 0
look_for1 = set(['This'])
look_for2 = set(['mb'])

files = glob.glob("*.extensionwanted")
for filename in files

    #Writing info wanted
    with open(filename,'rb') as inf, open('other_'+str(filename),'wb') as outf:
        incsv = csv.reader(inf, delimiter=',')
        outcsv = csv.writer(outf, delimiter=',')
        outcsv.writerows(row for row in incsv if look_for1 in row[col] and look_for2 in[col] )

    os.remove(filename)

答案 2 :(得分:1)

以下是如何选择所需的行并避免使用

所遇到的问题
outcsv.writerows(row for row in incsv if look_for1 in row[col] and 
                                        look_for2 in[col])

声明(有多个问题)。

我已经更新了我的答案,以说明如何使用glob模块将过滤应用于目录中的多个文件。

import csv
import glob
import os
import sys

def inplace_csv_file_filter(filepath, col, look_for):
    """ Remove rows in given csv file that contain all of the strings specified
        in look_for in the row[col] field.
    """
    backup_filepath = filepath + os.extsep + '.bak'
    try: os.unlink(backup_filepath)
    except os.error: pass
    os.rename(filepath, backup_filepath)
    with open(backup_filepath, mode='rb') as inf, open(filepath, 'wb') as outf:
        incsv = csv.reader(inf, delimiter=',')
        outcsv = csv.writer(outf, delimiter=',')
        outcsv.writerows(row for row in incsv
                            if not all(str_ in row[col] for str_ in look_for))
    # os.remove(backup_filepath)  # uncomment to delete backup file

col = 0
directory = './Directory'
pattern = '*.csv'
look_for = 'This', 'mb'

for filepath in glob.glob(os.path.join(directory, pattern)):
    inplace_csv_file_filter(filepath, col, look_for)