2017-03-17 11 views
0

の外に生成します。 Split one file into multiple files based on pattern (cut can occur within lines)ジェネレータの収量は、 "ここに(私は以下のようになってきている)@georgでトップの回答を参照して同期結果

私はこの分割する潜在的に有用なパターンを見つけます最初の区切り文字に基づいて、複数のファイルに分割します。 しかし、コメント作成者のメモによれば、最初に空白のファイルが作成されます。その理由は不明です。私はこれが私が持っている問題に関連していると思う。

私の(不器用、私はpythonマスターです!)の適応では、出力= next(fs)ジェネレータを呼び出すことによって、新しい出力ファイルを開く前に、区切り文字に続く行を解析してファイル名を設定しようとします。

しかし、ジレンマはドメイン名が区切り文字の後の行までわからないということです。私は含まれているデータと同期していない1つのステップであるファイル名で終わる。

入力ファイルはここ

<ns2:domain ... name="atypi.org" ..."> 

があるドメイン名が含まれ、このような行が続く標準

<?xml version='1.0' encoding='UTF-8'?> 

で始まるそれぞれの100+ xml「木」を、含まれている私現在のスクリプト:

#!/usr/bin/python2.7 

import re 

def files(): 
    n = 0 
    while n<12 : 
     n += 1 
     print "**DEBUG** in generator nameFile=%s n=%d \r" % (nameFile, n) 
     yield open('/Users/peterf/Google Drive/2015 Projects-Strategy/Domain Admin/RackDomains/%s.part.xml' % nameFile, 'w') 


filename='/Users/peterf/Google Drive/2015 Projects-Strategy/Domain Admin/RackspaceListDomain.output.xml' 
nameFile='' 
pat ='<?xml' 
namePat=re.compile('<ns2:domain.+ name="(.+?)".+>') 
fs = files() 
outfile = next(fs) 

with open(filename) as infile: 
    for line in infile: 
     m=namePat.search(line) 
     if m: 
      nameFile=m.group(1) 
      print "<---\rin 'if m:' nameFile=%s\r" % (nameFile) 
     if pat not in line: 
#   print "\rin 'pat not in line' line=%s\r" % (line)  
      outfile.write(line) 
     else: 
      items = line.split(pat) 
      outfile.write(items[0]) 
      for item in items[1:]: 
       print "in 'for item' pre next(fs) nameFile=%s\r" % (nameFile) 
       outfile = next(fs) 
       print "in 'for item' post next(fs) nameFile=%s --->\r" % (nameFile) 
       outfile.write(pat + item) 

私のデバッグリストは次のとおりです:

**DEBUG** in generator nameFile= n=1 

in 'for item' pre next(fs) nameFile= 

**DEBUG** in generator nameFile= n=2 

in 'for item' post next(fs) nameFile= ---> 

<--- 
in 'if m:' nameFile=addressing.com 

in 'for item' pre next(fs) nameFile=addressing.com 

**DEBUG** in generator nameFile=addressing.com n=3 

in 'for item' post next(fs) nameFile=addressing.com ---> 

<--- 
in 'if m:' nameFile=alicemcmahon.com 

in 'for item' pre next(fs) nameFile=alicemcmahon.com 

**DEBUG** in generator nameFile=alicemcmahon.com n=4 

in 'for item' post next(fs) nameFile=alicemcmahon.com ---> 

<--- 
in 'if m:' nameFile=alphabets.com 

in 'for item' pre next(fs) nameFile=alphabets.com 

**DEBUG** in generator nameFile=alphabets.com n=5 

in 'for item' post next(fs) nameFile=alphabets.com ---> 

出力ディレクトリは、私が推測する最初の「歩留まり」から切り捨てられた名前で始まる、これらのファイル名が含まれています...

.part.xml (this has data from 'addressing.com') 
addressing.com.part.xml 
alicemcmahon.com.part.xml 
alphabets.com.part.xml 
americanletterpress.com.part.xml 
americanwoodtype.com.part.xml 
amyshoemaker.com.part.xml 
archaicrevivalbooks.com.part.xml 
archaicrevivalfonts.com.part.xml 
archaicrevivalimages.com.part.xml 
astroteddies.com.part.xml 

私はこの問題にアプローチする方法を見つけ出すことはできません。ここで、ファイルの適切な名前を取得する前に、出力ファイルを生成しています。

はここで、入力ファイルのいくつかの代表的なセクションです:

<?xml version='1.0' encoding='utf-8'?> 
<ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns2="http://docs.rackspacecloud.com/dns/api/v1.0" xmlns="http://docs.rackspacecloud.com/dns/api/management/v1.0" id="1204245" name="addressing.com" ttl="300" emailAddress="[email protected]" updated="2012-10-10T21:33:36Z" created="2009-07-25T15:05:39Z"> 
    <ns2:nameservers> 
     <ns2:nameserver name="dns1.stabletransit.com" /> 
     <ns2:nameserver name="dns2.stabletransit.com" /> 
    </ns2:nameservers> 
    <ns2:recordsList totalEntries="5"> 
     <ns2:record id="A-2542579" type="A" name="addressing.com" data="198.101.155.141" ttl="300" updated="2012-10-10T21:33:35Z" created="2010-02-17T05:02:16Z" /> 
    </ns2:recordsList> 
</ns2:domain> 
<?xml version='1.0' encoding='UTF-8'?> 
<ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns2="http://docs.rackspacecloud.com/dns/api/v1.0" xmlns="http://docs.rackspacecloud.com/dns/api/management/v1.0" id="2776403" name="alicemcmahon.com" ttl="300" emailAddress="[email protected]" updated="2013-10-21T16:43:17Z" created="2011-05-01T03:01:51Z"> 
    <ns2:nameservers> 
     <ns2:nameserver name="dns1.stabletransit.com" /> 
     <ns2:nameserver name="dns2.stabletransit.com" /> 
    </ns2:nameservers> 
    <ns2:recordsList totalEntries="10"> 
     <ns2:record id="A-6895108" type="A" name="alicemcmahon.com" data="216.185.152.144" ttl="300" updated="2013-10-21T16:43:17Z" created="2011-05-01T03:01:51Z" /> 
    </ns2:recordsList> 
</ns2:domain> 
<?xml version='1.0' encoding='UTF-8'?> 
<ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns2="http://docs.rackspacecloud.com/dns/api/v1.0" xmlns="http://docs.rackspacecloud.com/dns/api/management/v1.0" id="1204247" name="americanletterpress.com" ttl="300" emailAddress="[email protected]" updated="2012-10-10T21:33:37Z" created="2009-07-25T15:05:41Z"> 
    <ns2:nameservers> 
     <ns2:nameserver name="dns1.stabletransit.com" /> 
     <ns2:nameserver name="dns2.stabletransit.com" /> 
    </ns2:nameservers> 
    <ns2:recordsList totalEntries="5"> 
     <ns2:record id="A-2542581" type="A" name="americanletterpress.com" data="198.101.155.141" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:02:16Z" />   
    </ns2:recordsList> 
</ns2:domain> 
<?xml version='1.0' encoding='UTF-8'?> 
<ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns2="http://docs.rackspacecloud.com/dns/api/v1.0" xmlns="http://docs.rackspacecloud.com/dns/api/management/v1.0" id="1204249" name="americanwoodtype.com" ttl="300" emailAddress="[email protected]" updated="2012-10-10T21:33:38Z" created="2009-07-25T15:05:42Z"> 
    <ns2:nameservers> 
     <ns2:nameserver name="dns1.stabletransit.com" /> 
     <ns2:nameserver name="dns2.stabletransit.com" /> 
    </ns2:nameservers> 
    <ns2:recordsList totalEntries="5"> 
     <ns2:record id="A-2542583" type="A" name="americanwoodtype.com" data="198.101.155.141" ttl="300" updated="2012-10-10T21:33:37Z" created="2010-02-17T05:02:16Z" /> 
    </ns2:recordsList> 
</ns2:domain> 

答えて

1

あなたは非常に開始時に出力ファイルを生成するために発電機を求めている:

右があなたの空白のファイル名です
nameFile='' 
# ... 
outfile = next(fs) 

。あなたがnameFileの値を持っていて、それ以前ではないまで、next(fs)を呼び出してください。あなたが書く前に

あなたはNoneのための代わりにoutfile = Noneとテストを設定できます

if pat not in line: 
    if outfile is not None: 
     outfile.write(line) 
else: 
    items = line.split(pat) 
    if outfile is not None: 
     outfile.write(items[0]) 

をあなたがあなたの最初のファイル名を見つけることができます前に、行を扱う代わりに、バッファ内のこれらの行を格納し、バッファをクリアする必要がある場合最初に新しいファイルを作成するとき。

ジェネレータをすべてに使用する必要があるとは思いませんが、実際には1つを使用して過度に複雑化しています。新しいファイルオブジェクトをループ内に直接作成してください。、これははるかに明確です。

あなたがやっているすべてのファイルを分割されている場合は、ファイル名を持つまで、バッファを使用します。

buffer = [] 
out_name = '/Users/peterf/Google Drive/2015 Projects-Strategy/Domain Admin/RackDomains/%s.part.xml' 

outfile = None 

with open(filename) as infile: 
    for line in infile: 
     # look for a filename to write to if we don't have one yet 
     if outfile is None: 
      match = namePat.search(line) 
      if match: 
       # New filename, open a file object 
       outfile = open(out_name % match.group(1), 'w') 
       # clear out the buffer, we'll write directly to 
       # the file after this. 
       outfile.writelines(buffer) 
       buffer = [] 

     if '<?xml' in line: 
      # new XML doc, close off the previous one 
      if outfile is not None: 
       outfile.close() 
      outfile = None 

     # line handling 
     if outfile is None: 
      buffer.append(line) 
     else: 
      outfile.write(line) 

if outfile is not None: 
    outfile.close() 
# All lines processed, if there is a buffer left, then we have unhandled lines 
if buffer: 
    print('There were trailing lines without a name') 
    print(*buffer, sep='') 
+0

おかげで@martijn!私は私のアプローチを修正します。いずれにせよ発電機について学ぶことは良いことでした;-) – pfraterdeus

+0

確かに非常に便利です!私の質問は+1の価値があったのですか? ;-) 私は1992年に私の最初のウェブサイトを作ったにもかかわらず、私はほとんどここから始めていません! https://web-beta.archive.org/web/199​​70708013523/http://www.alphabets.com:80/ – pfraterdeus

+0

@pfraterdeus:私はあなたが私たちの名刺を印刷したと信じています(私はJarn )!ちょうどそこにぶら下がり、忍耐は長期的に報われる。 –

関連する問題