2012-10-11 15 views
8

テストファイルを解析しようとしています。ファイルには、次の形式で、ユーザ名、住所と電話がありますのみ、ほぼ10Kのユーザーのためのテキストファイルを解析して列として出力するデータファイル

Name: John Doe1 
address : somewhere 
phone: 123-123-1234 

Name: John Doe2 
address : somewhere 
phone: 123-123-1233 

Name: John Doe3 
address : somewhere 
phone: 123-123-1232 

:)私がやりたいことは、たとえば、列にそれらの行を変換です:

Name: John Doe1    address : somewhere   phone: 123-123-1234 
Name: John Doe2    address : somewhere   phone: 123-123-1233 
Name: John Doe3    address : somewhere   phone: 123-123-1232 

私はbashでそれを行うことを好むでしょうが、もしあなたがそれをすばらしいものにする方法を知っていれば、この情報を持つファイルは/ root/docs/informationにあります。すべてのヒントや助けをいただければ幸いです。 Pythonで

+2

あなたは何を試しましたか? – nneonneo

+0

良い初期の質問、@ tafiela。しかし、あなたがしようとしていることを次の質問で指摘することを忘れないでください。 – Yamaneko

+0

アドレスはコロンの後の1行だけですか? –

答えて

5

一つの方法GNU awkと:

awk 'BEGIN { FS="\n"; RS=""; OFS="\t\t" } { print $1, $2, $3 }' file.txt 

結果:

Name: John Doe1  address : somewhere  phone: 123-123-1234 
Name: John Doe2  address : somewhere  phone: 123-123-1233 
Name: John Doe3  address : somewhere  phone: 123-123-1232 

出力ファイルのセパレータ(OFS)を2つのタブ文字(\t\t)に設定しました。これを任意の文字または文字セットに変更できます。 HTH。短いPerlワンライナーで

+0

+1 - あなたはパンチに私を打つ。 –

+0

「RS」とは何ですか? – Yamaneko

+1

@VictorHugo: 'RS'はレコードセパレータの略です。デフォルトでは、 'RS'は' \ n'または改行に設定されています。これは 'awk'が行ごとにファイルを処理することを可能にします。何も設定しない場合(または '' '')、awkの行の定義を実際に変更しています。それぞれのレコードは空行で区切られているので、 'RS =" "を設定すると簡単に解決できます。 HTH。 – Steve

0

results = [] 
cur_item = None 

with open('/root/docs/information') as f: 
    for line in f.readlines(): 
     key, value = line.split(':', 1) 
     key = key.strip() 
     value = value.strip() 

     if key == "Name": 
      cur_item = {} 
      results.append(cur_item) 
     cur_item[key] = value 

for item in results: 
    # print item 
+0

あなたはその言語を正確にする必要があります;) –

+0

@putnick私はあなたが意味することをかなり理解していません –

+0

ただ言語を言う:それはPythonです。 – Matthias

0

あなたは、文字列にsplit()方法を使用して、これを解析することができるはずです。

line = "Name: John Doe1" 
key, value = line.split(":") 
print(key) # Name 
print(value) # John Doe1 
3

$ perl -ne 'END{print "\n"}chomp; /^$/ ? print "\n" : print "$_\t\t"' file.txt 

OUTPUTは

Name: John Doe1   address : somewhere    phone: 123-123-1234 
Name: John Doe2   address : somewhere    phone: 123-123-1233 
Name: John Doe3   address : somewhere    phone: 123-123-1232 
1

これは、あなたが欲しいものを基本的にやっているようだ:

information = 'information' # file path 

with open(information, 'rt') as input: 
    data = input.read() 

data = data.split('\n\n') 

for group in data: 
    print group.replace('\n', '  ') 

出力:

あなたが行を反復処理すると、このような列にそれらを印刷することができ
Name: John Doe1  address : somewhere  phone: 123-123-1234 
Name: John Doe2  address : somewhere  phone: 123-123-1233 
Name: John Doe3  address : somewhere  phone: 123-123-1232  
0

-

for line in open("/path/to/data"): 
    if len(line) != 1: 
     # remove \n from line's end and make print statement 
     # skip the \n it adds in the end to continue in our column 
     print "%s\t\t" % line.strip(), 
    else: 
     # re-use the blank lines to end our column 
     print 
2

ペーストを使用して、我々は、ファイル内の行に参加することができます。

$ paste -s -d"\t\t\t\n" file 
Name: John Doe1 address : somewhere  phone: 123-123-1234 
Name: John Doe2 address : somewhere  phone: 123-123-1233 
Name: John Doe3 address : somewhere  phone: 123-123-1232 
+0

いいえ整形式=) –

+0

@sputnick True、これは難しい部分です。タブを展開するための無数のユーティリティがあります。 –

+0

はい、この場合、2本のパイプが必要です;) –

1

私はあなたが言及しなかった知っていますawkは、それがうまくあなたの問題を解決:

awk 'BEGIN {RS="";FS="\n"} {print $1,$2,$3}' data.txt 
0
#!/usr/bin/env python 

def parse(inputfile, outputfile): 
    dictInfo = {'Name':None, 'address':None, 'phone':None} 
    for line in inputfile: 
    if line.startswith('Name'): 
     dictInfo['Name'] = line.split(':')[1].strip() 
    elif line.startswith('address'): 
     dictInfo['address'] = line.split(':')[1].strip() 
    elif line.startswith('phone'): 
     dictInfo['phone'] = line.split(':')[1].strip() 
     s = 'Name: '+dictInfo['Name']+'\t'+'address: '+dictInfo['address'] \ 
      +'\t'+'phone: '+dictInfo['phone']+'\n' 
     outputfile.write(s) 

if __name__ == '__main__': 
    with open('output.txt', 'w') as outputfile: 
    with open('infomation.txt') as inputfile: 
     parse(inputfile, outputfile) 
0

sedを用いた溶液。

cat input.txt | sed '/^$/d' | sed 'N; s:\n:\t\t:; N; s:\n:\t\t:' 
  1. 第一パイプ、sed '/^$/d'、空白行を削除します。
  2. 第2パイプ、sed 'N; s:\n:\t\t:; N; s:\n:\t\t:'は、ラインを結合します。
 
Name: John Doe1  address : somewhere  phone: 123-123-1234 
Name: John Doe2  address : somewhere  phone: 123-123-1233 
Name: John Doe3  address : somewhere  phone: 123-123-1232 
1

ここでのソリューションのほとんどはちょうどあなたが読んでいるファイル内のデータを再フォーマットされています。多分それがあなたが望むすべてです。

実際にデータを解析する場合は、データ構造に入れます。 Pythonで

この例:

data="""\ 
Name: John Doe2 
address : 123 Main St, Los Angeles, CA 95002 
phone: 213-123-1234 

Name: John Doe1 
address : 145 Pearl St, La Jolla, CA 92013 
phone: 858-123-1233 

Name: Billy Bob Doe3 
address : 454 Heartland St, Mobile, AL 00103 
phone: 205-123-1232""".split('\n\n')  # just a fill-in for your file 
              # you would use `with open(file) as data:` 

addr={} 
w0,w1,w2=0,0,0    # these keep track of the max width of the field 
for line in data: 
    fields=[e.split(':')[1].strip() for e in [f for f in line.split('\n')]] 
    nam=fields[0].split() 
    name=nam[-1]+', '+' '.join(nam[0:-1]) 
    addr[(name,fields[2])]=fields 
    w0,w1,w2=[max(t) for t in zip(map(len,fields),(w0,w1,w2))] 

今、あなたはソートする自由を持っている、データベースに入れてフォーマットを変更するなど

これはソートされた、そのデータを使ってフォーマットを出力します。

for add in sorted(addr.keys()): 
    print 'Name: {0:{w0}} Address: {1:{w1}} phone: {2:{w2}}'.format(*addr[add],w0=w0,w1=w1,w2=w2) 

プリント:

Name: John Doe1  Address: 145 Pearl St, La Jolla, CA 92013 phone: 858-123-1233 
Name: John Doe2  Address: 123 Main St, Los Angeles, CA 95002 phone: 213-123-1234 
Name: Billy Bob Doe3 Address: 454 Heartland St, Mobile, AL 00103 phone: 205-123-1232 

dictキーで使用されている姓でソートされています。

は、今では地域コードによってソート印刷:

for add in sorted(addr.keys(),key=lambda x: addr[x][2]): 
    print 'Name: {0:{w0}} Address: {1:{w1}} phone: {2:{w2}}'.format(*addr[add],w0=w0,w1=w1,w2=w2) 

プリント:

Name: Billy Bob Doe3 Address: 454 Heartland St, Mobile, AL 00103 phone: 205-123-1232 
Name: John Doe2  Address: 123 Main St, Los Angeles, CA 95002 phone: 213-123-1234 
Name: John Doe1  Address: 145 Pearl St, La Jolla, CA 92013 phone: 858-123-1233 

しかし、あなたは、インデックス付き辞書にデータを持っているので、あなたが代わりに並べ替え、それを表として印刷することができますが郵便番号:

# print table header 
print '|{0:^{w0}}|{1:^{w1}}|{2:^{w2}}|'.format('Name','Address','Phone',w0=w0+2,w1=w1+2,w2=w2+2) 
print '|{0:^{w0}}|{1:^{w1}}|{2:^{w2}}|'.format('----','-------','-----',w0=w0+2,w1=w1+2,w2=w2+2) 
# print data sorted by last field of the address - probably a zip code 
for add in sorted(addr.keys(),key=lambda x: addr[x][1].split()[-1]): 
    print '|{0:>{w0}}|{1:>{w1}}|{2:>{w2}}|'.format(*addr[add],w0=w0+2,w1=w1+2,w2=w2+2) 

プリント:

|  Name  |    Address    | Phone  | 
|  ----  |    -------    | -----  | 
| Billy Bob Doe3| 454 Heartland St, Mobile, AL 00103| 205-123-1232| 
|  John Doe1| 145 Pearl St, La Jolla, CA 92013| 858-123-1233| 
|  John Doe2| 123 Main St, Los Angeles, CA 95002| 213-123-1234| 
関連する問題