【问题标题】:Convert part of row to columns将部分行转换为列
【发布时间】:2015-02-02 20:39:43
【问题描述】:

我有一个带有输入的文件:

rownum,identifier,items_in_list
1,"ABC",{(123),(345),(69),(95),(90),(83),(3A)}

预期输出为:

rownum,identifier,items_in_list
1,"ABC",123
1,"ABC",345
1,"ABC",69
1,"ABC",95
1,"ABC",90
1,"ABC",83
1,"ABC",3A

我尝试使用“awk”,但它用于将列中的所有项目转换为行,但我只需要一些列到行..

我的代码:

echo "1,"ABC",{(123),(345),(69),(95),(90),(83),(3A)}" | awk -vRS="{" 'NF'

但这会转换为:

1,ABC,
(123),(345),(69),(95),(90),(83),(3A)}

更新:

您的所有命令都可以正常工作,但是对于一个小故障,对不起,我是新手,我只能投票给一个作为答案。

谢谢!但是如果行没有多个数字并且只有一个数字,我会遇到麻烦。例如,采用这种格式:

输入

1,33262,"ABC",{(64)} 
1,33263,"ABC",{(66),(57)}

实际输出:

1,33262,SOME_FIELD_NAME 
1,33262,64 
1,33263,SOME_FIELD_NAME 
1,33262,65,66 

所需输出:

1,33262,SOME_FIELD_NAME,64 
1,33263,SOME_FIELD_NAME,65
1,33263,SOME_FIELD_NAME,66

更新:

Jotne 建议的代码的“实际输出”: awk -F, '{a=$1","$2;gsub(/[{()}]/,"");for (i=3;i

对不起,我的输入有时有 2 个前导字段,有时有 3-10 个前导字段,但我们要转换为列的行始终以 '{' 开头,各个数字包含在 '()' 和结尾该行由“}”表示。 Jotne 的代码适用于 2 个主要字段,但对于 3 个主要字段失败。有人可以建议一种通用的方法来解析字段吗?

【问题讨论】:

  • “实际输出”是什么? “ABC”去哪儿了? “SOME_FIELD_NAME”从何而来?为什么您的新输入有 3 个前导字段,而您的原始输入有 2 个?想想你真正想问什么问题,然后编辑你的问题,用准确的例子正确地陈述它,然后我们中的一些人可能会再看一遍,并再次尝试为你提供帮助。

标签: python awk rows unpivot


【解决方案1】:

这是awk的一种方法

awk -F, '{a=$1","$2;gsub(/[{()}]/,"");for (i=3;i<=NF;i++) print a","$i}' file
1,"ABC",123
1,"ABC",345
1,"ABC",69
1,"ABC",95
1,"ABC",90
1,"ABC",83
1,"ABC",3A

使用RS

awk -vRS=, '{gsub(/[{()}]/,"")} NR==1 {a=$1;next} NR==2 {a=a","$1;next} {print a","$1}' file
1,"ABC",123
1,"ABC",345
1,"ABC",69
1,"ABC",95
1,"ABC",90
1,"ABC",83
1,"ABC",3A

【讨论】:

  • 谢谢!但是如果行没有多个数字并且只有一个数字,我会遇到麻烦。例如,以这种格式:输入 1,33262,"ABC",{(64)} 实际输出:1,33262,SOME_FIELD_NAME 1,33262, 64 所需输出:1,33262,SOME_FIELD_NAME,64
  • 你能更新你原来的帖子吗?无法读取 cmets 中的数据。
【解决方案2】:

如果您仍在寻找 Python 解决方案:

input = '1,"ABC",{(123),(345),(69),(95),(90),(83),(3A)}'
for extra_char in '{}()"':
    input = input.replace(extra_char, '')
input_elems = input.split(',')
rownum, identifier = input_elems[0:2]
for item in input_elems[2:]:
    print rownum, identifier, item

【讨论】:

    【解决方案3】:

    基于 Python 的解决方案:

    import csv
    import re
    
    data = ['rownum,identifier,items_in_list',
            '1,"ABC",{(123),(345),(69),(95),(90),(83),(3A)}']
    
    reader = csv.reader(data)  # change data to open(filename, 'rb')
    pat = r'{*\(([0-9a-fA-F]+)\)}*'
    next(reader)
    for row in reader:
        for elem in row[2:]:
            mat = re.search(pat, elem).group(1)
            print(','.join([row[0], '"{}"'.format(row[1]), mat]))
    

    输出:

    1,"ABC",123
    1,"ABC",345
    1,"ABC",69
    1,"ABC",95
    1,"ABC",90
    1,"ABC",83
    1,"ABC",3A
    

    【讨论】:

      【解决方案4】:
      awk -F, '{gsub(/)./,ORS); gsub(/(^[^(]+)?[(]/,$1 OFS $2 OFS); printf "%s",$0}' file
      1,"ABC",123
      1,"ABC",345
      1,"ABC",69
      1,"ABC",95
      1,"ABC",90
      1,"ABC",83
      1,"ABC",3A
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-02
        • 1970-01-01
        • 1970-01-01
        • 2015-04-25
        • 2014-03-04
        • 2011-05-15
        • 2017-08-11
        相关资源
        最近更新 更多