我有以下设置
ITEM1 a
ITEM1 b
ITEM1 c
ITEM2 bla
ITEM2 ds
我想在一个简单的语句中将其转换为以下内容(如SQL中的STUFF)
ITEM1 a,b,c
ITEM2 bla,ds
知道怎么做吗?
答案 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