考虑以下文件:
foo,5
foo,7
foo,9
boo,5
boo,10
boo,10
我想要的是将与一条记录$2
相关的所有数据打印出来。$1
对于此示例,所需的输出将是:
foo,5,7,9
boo,5,10
答案1
解决方案awk
:
awk 'BEGIN{OFS=FS=","}!(($1,$2)in c){c[$1,$2]=1;r[$1]=r[$1] OFS $2}
END{for(i in r){print i r[i]}}' file
- 设置
OFS=FS
为一致性。 - 使用
awk
的多维数组记住$2
到目前为止遇到的值。仅当没有匹配项时才“继续”(!(($1,$2)in c)
)。 - 在第一次遇到新键时为多维数组提供一个“虚拟”值。
- 为了方便起见,将所需的输出字符串连接到另一个数组中。
- 在 处
END
,打印循环。- 请注意,循环迭代没有任何特定的顺序,
awk
如果需要,您可以使用 的排序功能。
- 请注意,循环迭代没有任何特定的顺序,
答案2
将数据解析为“哈希”或“关联数组”或“字典”或任何名称:
perl -F, -lane '$first{$F[0]}->{$F[1]} = (); END { print join(",", $_, sort { $a <=> $b } keys %{ $first{$_} } ) for keys %first }' < inputfile
答案3
bash 中没有 awk 的解决方案:
$ cat bla.txt
foo,5
foo,7
foo,9
boo,5
boo,10
boo,10
$ { buffer="";
while read i ; do
key="${i%,*}" ;
if [[ "$key" == "$oldkey" ]] ; then
idx="${i#*,}";
if [[ ! "$idx" == "$oidx" ]] ; then
buffer+=",$idx" ;
oidx="$idx";
fi ;
else
test -z $buffer || echo $buffer ;
oldkey="$key" ;
buffer="$i" ;
oidx="${i#*,}" ;
fi ;
done ; echo $buffer ; } < bla.txt
foo,5,7,9
boo,5,10
$
它不漂亮也不短,但是很有效。我也有兴趣看到 awk 的解决方案。
答案4
和gnu
datamash
:
datamash -t ',' -s -g 1 unique 2 <infile
输出中的值的顺序会有所不同,因为它们在处理之前已排序:
boo,10,5
foo,5,7,9