AWK重新格式化较大字符串中的结果(名称)部分

时间:2018-08-26 02:18:39

标签: python bash awk

我的目标是将名称从最后一位中间( LFM )格式化为第一中间名( FML ),它们是较大字符串的一部分。这里是一些示例数据:

  

名称,地址1,地址2
  史密斯得克萨斯州巴黎苹果路123号的乔·M
  亚当斯,加利福尼亚州萨利纳斯市第一街543号的基思·兰德尔
  价格蒂芙尼(Tiffany),纽约州纽约市第32街11232号   步行者科罗拉多州丹佛市西大街98号Karen E F

我想要的是:

  

姓名,地址1,地址2
Joe M 史密斯,巴黎苹果路123号   TX
Keith Randall 亚当斯,加利福尼亚州萨利纳斯1st Street 543
  Tiffany 价格,纽约州纽约市32nd Street 11232号
Karen E F   步行者,科罗拉多州丹佛市西大街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

如果有一种更简便的方法将找到的最后一个字符串放到最前面,我想听听一下,但这是我的真正兴趣...

我的问题是我想重新排序第一个逗号分隔字段的空格分隔字段(我在上面做了什么), ,但是还要打印其余的逗号分隔数据。

有没有一种方法可以将地址信息存储在变量中,并将其附加在以空格分隔的名称之后?

或者,我可以做某种嵌套拆分吗?

我目前正在bash中使用awk进行此操作,但愿意使用python / pandas或其他任何有效方法。

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

使用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

答案 1 :(得分:0)

以下 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:]))

答案 2 :(得分:0)

另一个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, ...

答案 3 :(得分:0)

$ 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