8

テストファイルを解析しようとしています。ファイルには、次の形式のユーザー名、住所、電話番号が含まれています。

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万人のユーザーのみ:)私がやりたいのは、それらの行を列に変換することです。次に例を示します。

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ますが、Pythonでそれを行う方法を知っているなら、それも素晴らしいでしょう、この情報を含むファイルは/ root / docs/informationにあります。ヒントやヘルプをいただければ幸いです。

4

11 に答える 11

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。

于 2012-10-11T03:00:00.933 に答える
3

短いPerlワンライナーで:

$ perl -ne 'END{print "\n"}chomp; /^$/ ? print "\n" : print "$_\t\t"' 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
于 2012-10-11T03:02:17.933 に答える
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
于 2012-10-11T03:04:06.337 に答える
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|
于 2012-10-11T16:44:04.857 に答える
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     
于 2012-10-11T03:02:57.907 に答える
1

awkについて言及していないことは知っていますが、問題をうまく解決します:

awk 'BEGIN {RS="";FS="\n"} {print $1,$2,$3}' data.txt
于 2012-10-11T03:06:58.063 に答える
0

Python の場合:

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
于 2012-10-11T02:57:42.760 に答える
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
于 2012-10-11T03:03:21.783 に答える
0

split()文字列のメソッドを使用してこれを解析できるはずです。

line = "Name: John Doe1"
key, value = line.split(":")
print(key) # Name
print(value) # John Doe1
于 2012-10-11T02:59:06.997 に答える
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:'は、ラインを結合します。
名前: John Doe1 住所: どこか 電話: 123-123-1234
名前: John Doe2 住所: どこか 電話: 123-123-1233
名前: John Doe3 住所: どこか 電話: 123-123-1232
于 2012-10-11T04:30:21.800 に答える
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)
于 2012-10-11T03:12:29.850 に答える