2014-07-22 230 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,想知道如何解決這個問題或達成解決方案嗎? –

相關問題