AWK переформатирует часть результатов (имен) в большую строку - PullRequest
0 голосов
/ 26 августа 2018

Моя цель - переформатировать имена от Last First Middle ( LFM ) до First Middle Last ( FML ), которые являются частью большой строки. Вот некоторые примеры данных:

Имя, Адрес1, Адрес2
Смит Джо М, 123 Apple Rd, Paris TX
Адамс Кит Рэндалл, 543 1-я улица, Салинас, Калифорния
Цена Тиффани, 11232, 32-я улица, Нью-Йорк, Нью-Йорк.
Walker Karen E F, 98 West Ave, Denver CO

Что бы я хотел:

Имя, адрес1, адрес2
Джо М Смит , 123 Apple Rd, Париж TX
Кит Рэндалл Адамс , 543 1-я улица, Салинас, Калифорния
Tiffany Цена , 11232, 32-я улица, Нью-Йорк, Нью-Йорк.
Karen E F Уокер , West West Ave 98, Денвер, Колорадо

Я знаю, как изменить порядок первого столбца, но в итоге я отбрасываю остальные данные строки:

# Return the first colum via comma seperation (name), then seperate by spaces
# If there are two strings but not three (only a last and first name),
# then change the order to first last.

awk -F, '{print $1}'| awk -F" " '$2!="" && $3=="" {print $2,$1}' >> names.txt
awk -F, '{print $1}'| awk -F" " '$3!="" && $4=="" {print $3,$1,$2}' >> names.txt
...# Continue to iterate column numbers

Если есть более простой способ поместить последнюю найденную строку и переместить ее вперед, я бы хотел услышать об этом, но вот мой реальный интерес ...

Моя проблема заключается в том, что я хочу изменить порядок полей, разделенных пробелами, в 1-м поле, разделенном запятыми (что я делал выше), , но затем также распечатать остальные данные, разделенные запятыми.

Есть ли способ сохранить информацию об адресе в переменной и добавить ее после разделенных пробелами имен?

В качестве альтернативы, я могу сделать какое-то вложенное разбиение?

В настоящее время я делаю это с помощью awk в bash, но хочу использовать python / pandas или любые другие эффективные методы.

Спасибо за помощь!

Ответы [ 4 ]

0 голосов
/ 26 августа 2018
$ awk '
    BEGIN { FS=OFS=", " }
    $1 ~ / / {
        last = rest = $1
        sub(/ .*/,"",last)
        sub(/[^ ]+ /,"",rest)
        $1 = rest " " last
    }
    { print }
' file
Name, Address1, Address2
Joe M Smith, 123 Apple Rd, Paris TX
Keith Randall Adams, 543 1st Street, Salinas CA
Tiffany Price, 11232 32nd Street, New York NY
Karen E F Walker, 98 West Ave, Denver CO
0 голосов
/ 26 августа 2018

Используя sed, выглядит ужасно, но работает:

sed -E '2,$s/^([^ ,]*) ([^ ,]*)( [^,]*)?/\2\3 \1/' in

и POSIX версия:

sed '2,$s/^\([^ ,]*\) \([^ ,]*\)\( [^,]*\)*/\2\3 \1/' in

выход:

Name, Address1, Address2
Joe M Smith, 123 Apple Rd, Paris TX
Keith Randall Adams, 543 1st Street, Salinas CA
Tiffany Price, 11232 32nd Street, New York NY
Karen E F Walker, 98 West Ave, Denver CO
0 голосов
/ 26 августа 2018

Еще один awk. Этот работает со строкой заголовка и Мадонной (то есть с полями из одного слова):

$ awk '                     # using awk
BEGIN{FS=OFS=","}           # csv
{
    n=split($1,a," ")       # split the first field to a
    for(i=n;i>1;i--)        # iterate back from the last element of a
        a[1]=a[i] " " a[1]  # prepending to the first element of a
    $1=a[1]                 # replace the first field with the first element of a
}1' file                    # output

Выход:

Name, Address1, Address2
Joe M Smith, 123 Apple Rd, Paris TX
Keith Randall Adams, 543 1st Street, Salinas CA
Tiffany Price, 11232 32nd Street, New York NY
Karen E F Walker, 98 West Ave, Denver CO
Madonna, ...
0 голосов
/ 26 августа 2018

Следующий скрипт AWK , какой бы уродливый он ни был, работает для ваших входов (работает с awk -F, -f script.awk):

{
 split($1, names, " "); 
 for (i=2; i<=length(names); i++) 
     printf("%s ", names[i]); 
 printf("%s, ", names[1]);
 for(i=2; i<NF; i++)
     printf("%s,", $i);
 print($NF)
}

Ввод:

Smith Joe M, 123 Apple Rd, Paris TX
Adams Keith Randall, 543 1st Street, Salinas CA
Price Tiffany, 11232 32nd Street, New York NY
Walker Karen E F, 98 West Ave, Denver CO

Вывод:

Joe M Smith,  123 Apple Rd, Paris TX
Keith Randall Adams,  543 1st Street, Salinas CA
Tiffany Price,  11232 32nd Street, New York NY
Karen E F Walker,  98 West Ave, Denver CO

То же решение в Python :

import sys
import re

for line in sys.stdin:
    parts = re.split('\s*,\s*', line)
    names = parts[0].split()
    print(", ".join([" ".join(names[1:] + names[:1])] + parts[1:]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...