从多行中创建逗号分隔列

时间:2016-02-29 13:18:16

标签: bash csv impala

我有以下设置

ITEM1   a
ITEM1   b
ITEM1   c
ITEM2   bla
ITEM2   ds

我想在一个简单的语句中将其转换为以下内容(如SQL中的STUFF)

ITEM1   a,b,c
ITEM2   bla,ds

知道怎么做吗?

5 个答案:

答案 0 :(得分:2)

Pure Bash(关联数组需要Bash 4.0或更高版本):

#!/bin/bash

# Associative array for aggregated lines
declare -A lines

# Append second column value to value of first column key
while read -r key value; do
    lines[$key]+="$value,"
done < "$1"

for key in "${!lines[@]}"; do    
    # Print key and comma separated values (last comma removed)
    printf "%s\t%s\n" "$key" "${lines[$key]%,}"
done

这将为第一列的每个值收集逗号分隔字符串中第二列的值。

然后第二个循环接受每个键,从该行的末尾删除逗号并打印键和逗号分隔的值。

对于示例输入,我们得到

$ ./SO.sh infile 
ITEM2   bla,ds
ITEM1   a,b,c

请注意,键的顺序是不确定的。

答案 1 :(得分:0)

可能不是最好的,但是起点

#!/bin/bash


FILE="input2.txt"

for item in $(cut -d" " -f1 $FILE | sort|uniq)
do
        printf "%s\t" $item
        grep $item $FILE | awk '{printf "%s"  $2","}'| sed "s/,$//g"
        printf "\n"
done

我已将此文件input2.txt用作输入:

ITEM1   a
ITEM1   b
ITEM1   c
ITEM2   bla
ITEM2   ds
ITEM3   ccc
ITEM3   ddd
ITEM4   ggg
ITEM4   k
ITEM1   34
ITEM2   435
ITEM1   ooo
ITEM4   kkk
ITEM3   353
ITEM1   sdfs

这是输出:

[shell] ➤ ./test2.sh
ITEM1   a,b,c,34,ooo,sdfs
ITEM2   bla,ds,435
ITEM3   ccc,ddd,353
ITEM4   ggg,k,kkk

此致

克劳迪奥

答案 2 :(得分:0)

对于已排序的列。克劳迪奥的剧本可能会更好。

#!/bin/awk -f

# file: a.awk (add chmod +x)
# start: ./a.awk infile.txt
{
        if (LAST_COL != $1) {
                print LAST_COL " " ITEMS
                ITEMS=$2
                LAST_COL = $1
        } else {
                ITEMS = ITEMS "," $2
        }
}

答案 3 :(得分:0)

使用awk:
您创建一个数组,第一个字段作为索引,内容是您想要的串联 对于输入文件的每一行,查看第一个字段是否已存储在数组“items”中。存储新的fiels或添加,的已知字段。 完成所有行后,打印数组。

awk '
   {
      if ($1 in items){
         items[$1]=items[$1] "," $2;
      } else {
         items[$1]=$2;
      }
   }
   END {
      for (key in items) print key "\t" items[key];
   }' input

答案 4 :(得分:0)

如果第一个单词(项目)被分组:

awk '{if (item == $1) printf ",%s",$2; else {if (item!="") {printf "\n";} printf "%s",$0;} item=$1 } END{printf "\n";}' input.txt