2012-10-11 15 views
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 
केवल लगभग 10 हजार से उपयोगकर्ताओं के लिए

: फ़ाइल उपयोगकर्ता नाम, पता और निम्न स्वरूप में फोन है

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/info में है। किसी भी सुझाव या मदद की सराहना की जाएगी।

+2

आपने क्या प्रयास किया? – nneonneo

+0

अच्छा प्रारंभिक प्रश्न, @ टाफीला। लेकिन, अगले प्रश्नों में इंगित करना न भूलें कि आपने क्या करने की कोशिश की है। – Yamaneko

+0

क्या पता वास्तव में कोलन के बाद केवल एक पंक्ति है? –

उत्तर

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) को दो टैब वर्ण (\t\t) पर सेट किया है। आप इसे किसी भी चरित्र या पात्रों के सेट में बदल सकते हैं। HTH।

+0

+1 - आपने मुझे पंच पर हराया। –

+0

क्या 'आरएस' करता है? – Yamaneko

+1

@VictorHugo: 'आरएस' रिकॉर्ड विभाजक के लिए छोटा है। डिफ़ॉल्ट रूप से 'आरएस'' \ n' या न्यूलाइन पर सेट है। यह लाइन से फ़ाइल लाइन को संसाधित करने के लिए 'awk' को अनुमति देता है। जब हम इसे कुछ भी सेट नहीं करते (या '" "'), हम वास्तव में एक रेखा की 'awk' की परिभाषा बदल रहे हैं। चूंकि प्रत्येक रिकॉर्ड खाली लाइनों से अलग होता है, इसलिए 'आरएस = "" सेटिंग को आसान समाधान के लिए बनाता है। 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

@sputnick मैं समझ नहीं पा रहा हूं कि आपका क्या मतलब है –

+0

बस भाषा कहें: यह पायथन है। – Matthias

0

आप एक स्ट्रिंग पर split() पद्धति का उपयोग करके इस पार्स करने के लिए सक्षम होना चाहिए:

line = "Name: John Doe1" 
key, value = line.split(":") 
print(key) # Name 
print(value) # John Doe1 
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 
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 सच है, लेकिन यह कठिन हिस्सा है। टैब का विस्तार करने के लिए असंख्य उपयोगिताओं हैं। –

+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. दूसरी पाइप, 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

समाधान यहाँ के अधिकांश बस फ़ाइल है कि आप पढ़ रहे हैं में डेटा को पुन: फ़ॉर्मेट कर रहे हैं। शायद वह सब जो आप चाहते हैं।

यदि आप वास्तव में डेटा को पार्स करना चाहते हैं, तो इसे डेटा संरचना में रखें।

अजगर में यह उदाहरण:

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|