2015-09-06 50 views
2

FILENAME1:Data_A_2015-07-29_16-25-55-313.txt的Python:文件名比較在文件夾中

文件名2:Data_B_2015-07-29_16-25-55-313.txt

我需要的所有酒坊比較文件夾,以確保每一個時間戳,有一個和一個B文件。

文件名的第二和百分之一秒的部分並不總是在這兩個文件中相同的,所以真正重要的是DATE_%H:%M - > 2頁的文件,每分鐘就是我正在尋找

(如: Data_A_2015-07-29_16-25-55-313.txtData_B_2015-07-29_16-25-54-200.txt屬於一起)

我嘗試下面的代碼:

for root,dirs,files in os.walk(source): 
for a_items in files: 
    if a_items.__contains__("A"): 
     A_ALL_List.append(a_items)   # One List with all A Files 
     a_1 = a_item.split('_')[1]   # A Part 
     a_2 = a_item.split('_',)[2]   # Date Part 
     a_3 = a_item.split('_')[3]   # TimeStamp %H%M%S%SS incl. .txt 
     a_4 = a_3.rsplit('.txt',1)[0]  # TimeStamp %H%N%S%SS excl. .txt 
     a_5 = a_4.rsplit ('-',1)[0]   # TimeStamp %H%M%S 
     a_6 = a_5.rsplit ('-',1)[0]   # TimeStamp %H%M 
     a_lvl1 = a_1 + '_' + a_2 +'_' + a_3 # A_Date_FULLTimeStamp.txt 
     A_Lvl1.append(a_lvl1)    # A_Date_TimeStamp.txt LIST 
     a_lvl2 = a_lvl1.rsplit('.txt',1)[0] # Split .txt 
     A_Lvl2.append(a_lvl2)    # A_Date_TimeStamp LIST 
     a_lvl3 = a_1 + '_' + a_2 + '_' + a_5 # A_Date_(%H%M%S)TimeStamp 
     A_Lvl3.append(a_lvl3)    # A_Date_(%H%M%S)TimeStamp LIST 
     a_lvl4 = a_2 + '_' + a_4    # Date_FULLTimeStamp 
     A_Lvl4.append(a_lvl4)    # Date_FULLTimeStamp LIST 
     a_lvl5 = a_2 + '_' + a_5    # Date_(%H%M%S)TimeStamp 
     A_Lvl5.append(a_lvl5)    # Date_(%H%M%S)TimeStamp LIST 
     a_lvl6 = a_2 + '_' + a_6    # Date_(%H%M)TimeStamp 
     A_Lvl6.append(a_lvl6)    # Date_(%H%M)TimeStamp LIST 
for b_items in files:      # Did the same for B now 
    if b_items.__contains__("B"): 
     B_All_List.append(b_items) 

這樣,我得到了僅包含我要比較的零件兩個文件名稱列表 - >如如果我比較列表A_Lvl6和B_Lvl6,我只會比較日期部分和時間戳中的小時和分鐘。

我想通了,有較多的B文件不是一個文件,這樣我就感動:

for Difference in B_Lvl6: # Data in B 
if Difference not in A_Lvl6: # Not in A 
    DiffList.append(Difference) 

這樣,我得到了數據的輸出,我沒有一個文件,但乙文件 - > DiffList

現在我想從該DiffList中查找相應的B文件(因爲沒有匹配的A文件)並將這些B文件移動到另一個文件夾 - >在主文件夾中應該只有A和B文件具有匹配時間戳(%H%M)

我的問題(最後):

  1. 如何管理最後一部分,我希望擺脫沒有TimeStamp合作伙伴的所有A或B文件。

  2. 我的方法是解決這個問題的正確方法還是完全瘋了?我已經使用Python 1.5周了,所以對包和教程的任何建議都會受到歡迎。

解決方法我用:

source='/tmp' 

import os 
import re` 
import datetime as dt 

pat=re.compile(r'^Data_(A|B)_(\d{4}-\d{2}-\d{2}_\d+-\d+-\d+-\d+)') 
def test_list(l): 
return (len(l)==2 and {t[1] for t in l}!=set('AB')) 

def round_time(dto, round_to=60): 
    seconds = (dto - dto.min).seconds 
    rounding = (seconds-round_to/2) // round_to * round_to 
    return dto + dt.timedelta(0,rounding-seconds,-dto.microsecond)    

fnames={} 
for fn in os.listdir(source): 
    p=os.path.join(source, fn) 
    if os.path.isfile(p): 
     m=pat.search(fn) 
     if m: 
      d=round_time(dt.datetime.strptime(m.group(2), '%Y-%m-%d_%H-%M-%S-%f'), round_to=60) 
      fnames.setdefault(str(d), []).append((p, m.group(1))) 

for k, v in [(k, v) for k, v in fnames.items() if not test_list(v)]: 
    for fn in v: 
     print fn[0] 
+0

我個人的選擇是使用正則表達式,可以提取文件名的有意義的部分。將這些數據饋送到正確的數據結構後,可以輕鬆實現差異化。例如,關鍵字是日期和關聯值的字典是A/B或任何值的列表或集合。 – pasztorpisti

+0

所以我會爲A和B文件創建一個詞典?聽起來不錯,我會看字典系統 –

+0

我知道使用正則表達式可能聽起來有點矯枉過正,但在這種情況下,我更喜歡做精確匹配而不是分割「某些東西」。通過這種方式,處理多個不同的文件名模式變得更加容易,並且檢測未處理的模式非常簡單。使用命名的正則表達式組處理模式的有用部分的代碼更具可讀性,您可以通過名稱而不是索引來查詢組。 – pasztorpisti

回答

1

鑑於這五個文件名:

$ ls Data* 
Data_A_2015-07-29_16-25-55-313.txt 
Data_B_2015-07-29_16-25-54-200.txt 
Data_A_2015-07-29_16-26-56-314.txt 
Data_B_2015-07-29_16-26-54-201.txt 
Data_A_2015-07-29_16-27-54-201.txt 

您可以使用正則表達式來定位的關鍵信息:Demo

由於我們正在處理時間戳,所以時間應該四捨五入到最近的關注時間標記。

這裏是將圓向上或向下到最接近的分功能:

import datetime as dt 

def round_time(dto, round_to=60): 
    seconds = (dto - dto.min).seconds 
    rounding = (seconds+round_to/2) // round_to * round_to 
    return dto + dt.timedelta(0,rounding-seconds,-dto.microsecond) 

再加上循環儘管文件,可以組合成一個列表的字典的鍵是時間戳四捨五入到一分鐘。

(我懷疑你的文件都在同一目錄中,所以我這個展示與os.listdir而不是os.walk因爲os.walk通過多個目錄遞歸進入)

import os 
import re 
import datetime as dt 

pat=re.compile(r'^Data_(A|B)_(\d{4}-\d{2}-\d{2}_\d+-\d+-\d+-\d+)') 

fnames={} 
for fn in os.listdir(source): 
    p=os.path.join(source, fn) 
    if os.path.isfile(p): 
     m=pat.search(fn) 
     if m: 
      d=round_time(dt.datetime.strptime(m.group(2), '%Y-%m-%d_%H-%M-%S-%f'), round_to=60) 
      fnames.setdefault(str(d), []).append((p, m.group(1))) 

print fnames 

打印:

{'2015-07-29 16:28:00': [('/tmp/Data_A_2015-07-29_16-27-54-201.txt', 'A')], '2015-07-29 16:27:00': [('/tmp/Data_A_2015-07-29_16-26-56-314.txt', 'A'), ('/tmp/Data_B_2015-07-29_16-26-54-201.txt', 'B')], '2015-07-29 16:26:00': [('/tmp/Data_A_2015-07-29_16-25-55-313.txt', 'A'), ('/tmp/Data_B_2015-07-29_16-25-54-200.txt', 'B')]} 

的五個文件有一個文件不具有對。您可以篩選所有不是長度爲2或沒有A和B匹配的文件列表。

首先,定義一個測試功能,會在測試:

def test_list(l): 
    return (len(l)==2 and {t[1] for t in l}==set('AB')) 

然後用列表解析找到所有從字典不符合你條件的條目:

>>> [(k, v) for k, v in fnames.items() if not test_list(v)] 
[('2015-07-29 16:28:00', [('/tmp/Data_A_2015-07-29_16-27-54-201.txt', 'A')])] 

然後對這些文件採取行動:

for k, v in [(k, v) for k, v in fnames.items() if not test_list(v)]: 
    for fn in v: 
     print fn # could be os.remove(fn) 

相同的基本方法適用於os.walk但您可能有多個目錄中的文件。

下面是完整列表:

source='/tmp' 

import os 
import re 
import datetime as dt 

pat=re.compile(r'^Data_(A|B)_(\d{4}-\d{2}-\d{2}_\d+-\d+-\d+-\d+)') 

def test_list(l): 
    return (len(l)==2 and {t[1] for t in l}==set('AB')) 

def round_time(dto, round_to=60): 
    seconds = (dto - dto.min).seconds 
    rounding = (seconds+round_to/2) // round_to * round_to 
    return dto + dt.timedelta(0,rounding-seconds,-dto.microsecond)    

fnames={} 
for fn in os.listdir(source): 
    p=os.path.join(source, fn) 
    if os.path.isfile(p): 
     m=pat.search(fn) 
     if m: 
      d=round_time(dt.datetime.strptime(m.group(2), '%Y-%m-%d_%H-%M-%S-%f'), round_to=60) 
      fnames.setdefault(str(d), []).append((p, m.group(1))) 

for k, v in [(k, v) for k, v in fnames.items() if not test_list(v)]: 
    for fn in v: 
     print fn[0] # This is the file that does NOT have a pair -- delete? 
+0

哇謝謝,看起來很有希望!然而,最後的部分對我來說不是很清楚。我必須在哪裏放? '[(k,v)for k,v in fnames.items()if test_list(v)]' –

+0

圓文件存在問題:'Data_A_2015-07-29_16-25-55-313.txt'會收到16:26 - >但它是一個文件的時間戳16-25,或者我看到這個woring –

+0

'{'2015-07-29_16-26':['/ tmp/Data_A_2015-07-29_16 -25-55-313.txt','/ tmp/Data_B_2015-07-29_16-25-54-200.txt'],' –

1

我想後了部分答案指出瞭如何分配分割的結果名稱,並給他們有意義的名字。這通常會使問題更容易解決。

def match_files(files): 
    result = {} 

    for filename in files: 
     data, letter, date, time_txt = filename.split('_') 
     time, ext = time_txt.split('.') 
     hour, min, sec, ns = time.split('-') 

     key = date + '_' + hour + '-' + min 

     # Initialize dictionary if it doesn't already exist. 
     if not result.has_key(key): 
      result[key] = {} 

     result[key][letter] = filename 


    return result 



filename1 = 'Data_A_2015-07-29_16-25-55-313.txt' 
filename2 = 'Data_B_2015-07-29_16-25-55-313.txt' 

file_list = [filename1, filename2] 


match_files(file_list) 

輸出:

In [135]: match_files(file_list) 
Out[135]: 
{'2015-07-29_16-25': {'A': 'Data_A_2015-07-29_16-25-55-313.txt', 
    'B': 'Data_B_2015-07-29_16-25-55-313.txt'}} 
+0

好,真正使更多的意義:-)謝謝 –

2

我想簡單地忽略了第二和毫秒部分是不是一個好主意。可能會發生這樣的情況,其中一個文件的格式爲01:01:59:999,而另一個文件的格式爲01:02:00:000。差別只有一毫秒,但它也會影響分鐘部分。更好的解決方案是解析日期時間並計算它們之間的時間間隔。但讓我們來看看這個簡單的愚蠢版本。我認爲這樣的事情可以完成這項工作。它滿足你的需要,如果它不正是你需要的:

import os 
import re 

pattern = re.compile(r'^Data_(?P<filetype>A|B)_(?P<datetime>\d\d\d\d\-\d\d\-\d\d_\d\d\-\d\d)\-\d\d\-\d\d\d\.txt$') 

def diff_dir(dir, files): 
    a_set, b_set = {}, {} 
    sets = {'A': a_set, 'B': b_set} 
    for file in files: 
     path = os.path.join(dir, file) 
     match = pattern.match(file) 
     if match: 
      sets[match.group('filetype')][match.group('datetime')] = path 
     else: 
      print("Filename doesn't match our pattern: " + path) 
    a_datetime_set, b_datetime_set = set(a_set.keys()), set(b_set.keys()) 
    a_only_datetimes = a_datetime_set - b_datetime_set 
    b_only_datetimes = b_datetime_set - a_datetime_set 
    for dt in a_only_datetimes: 
     print(a_set[dt]) 
    for dt in b_only_datetimes: 
     print(b_set[dt]) 

def diff_dir_recursively(rootdir): 
    for dir, subdirs, files in os.walk(rootdir): 
     diff_dir(dir, files) 

if __name__ == '__main__': 
    # use your root directory here 
    rootdir = os.path.join(os.path.dirname(__file__), 'dir') 
    diff_dir_recursively(rootdir) 
+0

謝謝,但據I'm通知測量是在同一分鐘所有loged,所以我不會鬆動文件,因爲一個01:01:59:999另一個有01:02:00:000的場景...我希望:-)感謝您的代碼我會試試 –