Вопрос по python, bash, parsing, scripting – Строки разбора данных текстового файла и вывод в виде столбцов

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

Что ты пробовал? nneonneo
Адрес действительно только одна строка после двоеточия? user648852
Хороший начальный вопрос, @tafiela. Но нене забудьте указать в следующих вопросах, что вы пытались сделать. Yamaneko

Ваш Ответ

11   ответов
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)
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|
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
@sputnick Правда, но это самая сложная часть. Есть множество утилит для расширения вкладок. luser droog
Нет так хорошо отформатирован =) Gilles Quenot
Да, но в этом случае вам нужно 2 трубы;) Gilles Quenot
0

Решение с использованием.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
0

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

line = "Name: John Doe1"
key, value = line.split(":")
print(key) # Name
print(value) # John Doe1
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     
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). Вы можете изменить это на любой символ или набор символов, пожалуйста. НТН.

КакиеRS делает? Yamaneko
@Виктор Гюго:RS сокращение от разделителя записей. По умолчаниюRS установлен в\n или перевод строки. Это позволяетawk обрабатывать файл построчно. Когда мы устанавливаем это в ничто (или"") мына самом деле меняетсяawkопределение линии. Поскольку каждая из записей разделена пустыми строками, настройкаRS="" делает для простого решения. НТН. Steve
@steve - спасибо, теперь понятно Yamaneko
+1 - ты избил меня до удара. Hai Vu
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
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
1

awk 'BEGIN {RS="";FS="\n"} {print $1,$2,$3}' data.txt
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
Вы должны уточнить язык;) Gilles Quenot
@sputnick I 'Я не совсем понимаю, что вы имеете в виду Nathan Villaescusa
Просто скажи на языке:с Python. Matthias

Похожие вопросы