是否可以将awk
用于同一个键的值到一行?
例如
a,100
b,200
a,131
a,102
b,203
b,301
我可以将它们转换为这样的文件:
a,100,131,102
b,200,203,301
答案 0 :(得分:5)
您可以像这样使用awk:
awk -F, '{a[$1] = a[$1] FS $2} END{for (i in a) print i a[i]}' file
a,100,131,102
b,200,203,301
我们使用-F,
将逗号用作分隔符,并使用数组a
来保持聚合值。
答案 1 :(得分:1)
如果Perl是一个选项,
perl -F, -lane '$a{$F[0]} = "$a{$F[0]},$F[1]"; END{for $k (sort keys %a){print "$k$a{$k}"}}' file
使用以下命令行选项:
-n
循环输入文件的每一行-l
在处理之前删除换行符,然后将其添加回来-a
autosplit模式 - 将输入行拆分为@F
数组。默认为在空格上拆分。 -e
执行perl代码-F
autosplit修饰符,在这种情况下会在,
@F
是每行中的单词数组,从$F[0]
开始编制索引
$F[0]
是@F
(关键)中的第一个元素
$F[1]
是@F
(值)中的第二个元素
%a
是一个哈希,它存储一个包含每个键的所有匹配项的字符串
答案 2 :(得分:0)
如果您预先输入输入,则可以使用sed
来加入这些行,例如:
sort foo | sed -nE ':a; $p; N; s/^([^,]+)([^\n]+)\n\1/\1\2/; ta; P; s/.+\n//; ba'
上述单行可以保存到脚本文件中。请参阅下面的注释版本。
parse.sed
# A goto label
:a
# Always print when on the last line
$p
# Read one more line into pattern space and join the
# two lines if the key fields are identical
N
s/^([^,]+)([^\n]+)\n\1/\1\2/
# Jump to label 'a' and redo the above commands if the
# substitution command was successful
ta
# Assuming sorted input, we have now collected all the
# fields for this key, print it and move on to the next
# key
P
s/.+\n//
ba
这里的逻辑如下:
像这样运行:
sort foo | sed -nEf parse.sed
输出:
a,100,102,131
b,200,203,301
答案 3 :(得分:0)
使用datamash
$ datamash -st, -g1 collapse 2 <ip.txt
a,100,131,102
b,200,203,301
摘自手册:
-s,--sort
在分组之前对输入进行排序;这样就无需手动通过“ sort”通过管道传递输入
-t,--field-separator = X
使用X代替TAB作为字段分隔符
-g,--group = X [,Y,Z]
通过字段X,[Y,Z]
分组折叠
所有输入值的逗号分隔列表