从多行中生成逗号分隔列

63lcw9qa  于 2021-06-26  发布在  Impala
关注(0)|答案(5)|浏览(239)

我有以下设置

ITEM1   a
ITEM1   b
ITEM1   c
ITEM2   bla
ITEM2   ds

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

ITEM1   a,b,c
ITEM2   bla,ds

你知道怎么做吗?

mlmc2os5

mlmc2os51#

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

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
4zcjmb1e

4zcjmb1e2#

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


# !/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
        }
}
ne5o7dgx

ne5o7dgx3#

也许不是最好的,但却是一个起点


# !/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

当做
克劳迪奥

3mpgtkmj

3mpgtkmj4#

纯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

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

zpjtge22

zpjtge225#

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

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

相关问题