Строки разбора данных текстового файла и вывод в виде столбцов

Я пытаюсь разобрать тестовый файл. файл имеет имя пользователя, адрес и телефон в следующем формате:

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 но если вы знаете, как это сделать на python, это тоже было бы здорово, файл с этой информацией находится в / root / docs / information. Любые советы или помощь будут высоко ценится.

 nneonneo11 окт. 2012 г., 04:56
Что ты пробовал?
 Yamaneko11 окт. 2012 г., 05:25
Хороший начальный вопрос, @tafiela. Но нене забудьте указать в следующих вопросах, что вы пытались сделать.
 user64885211 окт. 2012 г., 05:46
Адрес действительно только одна строка после двоеточия?

Ответы на вопрос(11)

Решение Вопроса

Один из способов с: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). Вы можете изменить это на любой символ или набор символов, пожалуйста. НТН.

 Hai Vu11 окт. 2012 г., 05:08
+1 - ты избил меня до удара.
 Steve11 окт. 2012 г., 05:20
@Виктор Гюго:RS сокращение от разделителя записей. По умолчаниюRS установлен в\n или перевод строки. Это позволяетawk обрабатывать файл построчно. Когда мы устанавливаем это в ничто (или"") мына самом деле меняетсяawkопределение линии. Поскольку каждая из записей разделена пустыми строками, настройкаRS="" делает для простого решения. НТН.
 Yamaneko11 окт. 2012 г., 05:22
@steve - спасибо, теперь понятно
 Yamaneko11 окт. 2012 г., 05:15
КакиеRS делает?

В 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
 Gilles Quenot11 окт. 2012 г., 05:09
Вы должны уточнить язык;)
 Matthias11 окт. 2012 г., 08:12
Просто скажи на языке:с Python.
 Nathan Villaescusa11 окт. 2012 г., 05:23
@sputnick I 'Я не совсем понимаю, что вы имеете в виду

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
#!/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)

который вы читаете. Может быть, это все, что вы хотите.

Если вы действительно хотите проанализировать данные, поместите их в структуру данных.

Этот пример в 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|

Решение с использованием.sed

cat input.txt | sed '/^$/d' | sed 'N; s:\n:\t\t:; N; s:\n:\t\t:'
Первая труба,sed '/^$/d', удаляет пустые строки.Вторая труба,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

Вы должны быть в состоянии разобрать это с помощьюsplit() метод на строку:

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

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     

С коротким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

$ 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
 luser droog11 окт. 2012 г., 09:15
@sputnick Правда, но это самая сложная часть. Есть множество утилит для расширения вкладок.
 Gilles Quenot11 окт. 2012 г., 05:14
Нет так хорошо отформатирован =)
 Gilles Quenot11 окт. 2012 г., 15:12
Да, но в этом случае вам нужно 2 трубы;)

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

Ваш ответ на вопрос