2013-03-19 214 views
-3

我對python非常陌生,每天都會學到很多東西。 我想做一個自動腳本,這將有助於我的工作。在目錄中搜索包含文件夾路徑的特定文件並將其複製到Python中

我有一個包含一些文件的特定文件夾,我不希望我的工具,是具體的文件,因爲我想,所以我希望它在文件中查找特定的標題重複使用這個腳本,

可以說文件在中間的某處有「路徑」,在它的下面有很多路徑,比如「file path =」Some path「

我希望我的腳本進入我指定的目錄並查找包含這個標題「路徑」 複製其中一條路徑(它們將在它下面)並且就是它。

然後我去要使用此路徑下載文件和更多,但這部分我已經完成。 我只是不知道如何在給定特定文件夾時查找文件中的特定字符串並複製我想要的字符串。

所以,可以說,我有一個文件夾(C:\文件夾) ,文件夾中,我有3個文件(1,2,3)

我想尋找含有這種模式的文件「路徑「 並複製路徑或其中至少一個指定的路徑。 他們會像 「文件路徑= C:\ somepath」 所以文件內容是像

布拉布拉

布拉布拉

路徑

文件路徑= C:\ somepath

file path = C:\ somepath2

blabla

我想複製C:\ somepath並將其用作我工作的一部分。

非常感謝所有幫手,這對我來說更重要。

+0

好吧,如果你期待幫助,你應該先用適當的英語解釋你的問題。 現在,不可能遵循你想說的話,用你的標點和語法搞砸了。 – geenux 2013-03-28 00:12:24

回答

1

第一步是查看目錄中的所有文件。那是os.listdir

接下來,您需要在循環中打開每個文件。所以,到目前爲止,我們得到了:

for filename in os.listdir(directory): 
    with open(filename) as f: 

現在,我們對每個文件做什麼?有幾個不同的選項 - 我們可以在整個文件(或mmap它)中讀取,然後使用str.find或正則表達式方法來解析它,或者我們可以一行一行地跟蹤我們的狀態,或者我們可以轉換我們可以建立一個狀態機並運行它,或者...

我認爲對於新手來說最簡單的就是手動逐行執行。但讓我們把它包裝在一個函數中。所以:

def parse_file(f): 
    paths = [] 
    found_paths = False 
    for line in f: 
     line = line.strip() 
     if not found_paths: 
      if line == 'paths': 
       found_paths = True 
     else: 
      if line.startswith('file path='): 
       paths.append(line[len('file path='):]) 
      else: 
       break 
    return paths 

paths = [] 
for filename in os.listdir(directory): 
    with open(filename) as f:    
     paths.append(parse_file(f)) 

我怎樣才能找到第一個行後停止?

只讀break看完第一行後。所以,與其這樣:

if line.startswith('file path='): 
    paths.append(line[len('file path='):]) 
else: 
    break 

這樣做:

if line.startswith('file path='): 
    paths.append(line[len('file path='):]) 
break 

我怎麼能解決這個問題就擺在不同的指數的路徑在字典中,因爲它把所有的人都在第一場

那麼現在,你是不是創建一個字典,你要創建一個列表。

如果您想要一個字典,將每個文件映射到該文件中的文件路徑列表,這很容易。取而代之的是:

paths = [] 
for filename in os.listdir(directory): 
    with open(filename) as f: 
     paths.append(parse_file(f)) 

這樣做:

paths = {} 
for filename in os.listdir(directory): 
    with open(filename) as f:    
     paths[filename] = parse_file(f) 

但是,它可能是簡單的不能建立在首位的列表,如果你只想要一個值。如果你找到一個,你只需要返回路徑名,如果你不這樣做的話,它不可能是一個路徑名(如None)。

我該如何修改有問題的路徑。因爲文件的路徑保存在這種格式 - 我只想複製C:\文件夾\文件夾

嗯,首先,我的代碼甚至不會找到與該格式事情。您要求找到像file path=…這樣的行,因此我使用了startswith,但<file path=不以此開頭。所以你首先需要改變你檢查的startswith。同時,您還需要處理引號和尖括號。

在這一點上,它看起來像只是愚蠢的文字處理可能不是正確的答案。這看起來像XML。解析XML文檔的最簡單方法是使用XML解析器,如xml.elementtree。如果它不是一個XML文件,只要有卡在它的XML節點基於行的文件,你可以仍然嘗試解析每行一個XML文檔,但它可能是更容易使用re用合適的正則表達式(例如,r'<file path="(.*?)"/>'將僅匹配引號之間的部分)。不知道你的實際輸入文本的樣子,我不能給你任何東西比這更具體。

最後,在完成該步驟後,它看起來像要從目錄路徑中刪除尾部反斜槓,所以即使該文件有C:\folder\folder\,也會得到C:\folder\folder。你可以在os.path此使用的功能,但如果你確定的路徑總是會在Windows格式,它可以更簡單,只是告訴它刪除任何尾隨的反斜槓,與rstrip('\\')。 (請注意那裏的雙反斜槓,因爲您需要在Python字符串中跳出反斜槓。)

+0

非常感謝,但我有幾個問題。如何在找到第一行後停下來?或者我可以如何修復它把路徑放在字典中的不同索引中,因爲它將所有這些路徑放在第一個字段中(並且最終我想使用它)第二個問題是如何修改有問題的路徑。因爲文件中的路徑以這種格式保存 - <文件路徑=「C:\文件夾\文件夾\」/>,我只想複製C:\文件夾\文件夾。謝謝!!! – 2013-03-20 00:31:01

+0

既然你有很多問題,讓我更新答案。 – abarnert 2013-03-20 00:50:09

+0

好吧,不需要第一個問題的答案,我只是做路徑[0] [0]但我如何操縱路徑,腳本的結果現在是文件中的「C:\ folder \ folder \」/>它是<文件路徑=「C:\文件夾\文件夾\」/> - 我想要的結果是C:\文件夾\文件夾 - 謝謝! – 2013-03-20 00:50:30

-1

根據您的意見,您的數據實際上是XML,而您想要的是第一個paths節點中每個(或第一個)節點的path屬性。

就XML解析器而言,這實際上更容易編寫,並且更加健壯。

例如,這些可能都有效file節點:

<file path="C:\Foo\Bar" /> 
<file path="C:\Baz\Qux"/> 
    <file path="C:\Foo\Bar" /> 
<file path="C:\Spam\Eggs\" alt="other attribute cruft" /> 
<file alt="other attribute cruft" path="C:\Spam\Eggs\" /> 
<file path="C:\Spam\Spam\"></file> 

而且你甚至可以看到這些,合法與否:

<file path='C:\Eggs\"Spam Spam Spam"\"Spammity Spam"'/> 

你不想嘗試處理所有在純文本中的可能性。但是,如果你不處理所有這些 - 而且更重要的是 - 墨菲定律可以保證你最終會碰到一個你無法處理的文件。

有很多不同的XML解析器,甚至內置到標準庫中,但我認爲最簡單的是ElementTree。所以:

import os 
import os.path 
import xml.etree.ElementTree as ET 

filepaths = {} 
for filename in os.listdir(directory): 
    try: 
     doc = ET.parse(os.path.join(directory, filename)) 
     paths = doc.find('paths') 
     filepaths[filename] = [f.attrib['path'] for f in paths.findall('file')] 
    except Exception as e: 
     # You may want to log something, treat different exceptions differently, etc. 
     pass 

這應該是很容易弄清楚如何改變這種處理所有paths節點,而不是第一個,或paths,而不是所有的人都在第一file節點,或第一file節點時具有path屬性等

如果您使用的是Python 2.x,並且這些文件非常大,則可能會有點慢。但是你可以通過明確使用cElementTree來解決這個問題。這是很常見的做到這一點:

try: 
    import xml.etree.cElementTree as ET 
except ImportError: 
    import xml.etree.ElementTree as ET 

如果可能會給你快「C」的實施,緩慢的一個,否則,在CPython的2.5+(包括3.x中,其中兩個被合併在一起) PyPy等


同時,從其他意見,你要的那種沒有在原來的崗位額外的東西:

我只需要......使反斜槓/

這很簡單。請在每個路徑s上撥打s.replace('\\', '/')

但是,這是一件很奇怪的事情。其他方式很常見(它甚至內置於標準庫中 - os.path.normpath將在POSIX上單獨使用斜槓,但將它們轉換爲Windows上的反斜槓),但從本地Windows到POSIX通常是較大操作的一部分,比如構建一個URL ......在這種情況下,您可能想要使用更高級別的功能。

它在文件中

- 結果我要的是C:\文件夾\文件夾

這裏,這聽起來像你想去掉所有斜槓。再一次,這是一件很奇怪的事情,你可能實際上想要做比這更高級的事情(比如os.path.dirname也許?),但很容易:s.rstrip('\\')

當然這些最後兩個相互矛盾 - 如果你想要的結果是C:\folder\folder,並且你將反斜槓轉換爲正斜槓,你不會得到你想要的結果。

但希望我給了你足夠的建設,無論你真正想要什麼。

+0

我不知道我做錯了什麼,我的文件看起來像這樣 - 和它下面<文件路徑=「C:\文件夾\文件夾\」/>和更多路徑在相同的格式,它結束後在文件的頂部,在底部還有更多的東西。我運行你寫的代碼,我在filepaths中得到的代碼是空的{},並且在我得不到的路徑中。行! – 2013-03-20 02:57:04

+0

行!我得到了解決方案!謝謝你的出色幫助! – 2013-03-20 03:23:42

+0

誰低估,謹慎解釋爲什麼? – abarnert 2013-03-20 19:07:27

相關問題