2014-07-22 231 views
1

我有一个包含具有多个扩展名的文件的目录,但我只对使用特定的文件感兴趣。将更改应用于同一目录中的多个文件

  • 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”在同一时间的第一列,想要的结果将是:

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和我想要循环延期。 我有点失落在动态环境中执行此操作,而不是使用静态文件名。有人能帮我一把吗?

+0

输出必须转到每个文件inputp的唯一文件或文件输出? – Trimax

+0

“我有点失落”太含糊 - 你想要做什么方面让你烦恼? – martineau

+0

@Informatico_Sano扩展文件没有意义。重要的是它的格式。来自毕尔巴鄂的一个人给了这个文件两个踢腿,并且它已经修复了。 _Ahíva la hostia!_ ;-) – Trimax

回答

1

下面是如何选择您想要的行,并避免你与

outcsv.writerows(row for row in incsv if look_for1 in row[col] and 
             look_for2 in[col]) 

语句有问题(S)(其中有多个问题)。

我已更新我的答案,以说明如何使用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) 
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文件循环。

+0

好吧,我的问题没有附带扩展名(另外做你说我需要添加一行'如果file.endswith('。wantedextension')',因为有不同种类的文件),但与循环,稍后写入。我卡在那里 –

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) 
+0

首先感谢您的答案,但代码给了我一个错误'outcsv.writerows(rows in incsv行,如果look_for1行[col]和look_for2 [col])',这是我试图避免_TypeError。 '在'需要字符串作为左操作数,而不是set_ 我也导入库字符串,btw。我怎么能解决这个问题? 预先致谢 –

+0

@The2ndSon'look_for1'和'look_for2'是列表集合,并且在您的表达式'look_for1 in row [col]和look_for2 in [col]'中,您不能使用in操作符来验证如果一个'set'对象(或一个'list'对象是一个'string'类型的对象)。 – Trimax

+0

您好@Trimax,想知道如何解决这个问题或达成解决方案吗? –

相关问题