从shell

时间:2016-02-09 10:06:08

标签: linux shell

我有一个看起来像这样的csv文件

John,Smith, 2, 3
John,Smith, 2, 3
John,Smith, 1, 4
John,Smith, 6, 2
Adam,Brown, 2, 3
Adam,Brown, 5, 6
Adam,Brown, 1, 1
Thom,Bow, 1, 5

我希望按照出现的顺序为每个出现的名字和姓氏保留前k行。 k = 2的输出应为

John,Smith, 2, 3
John,Smith, 2, 3
Adam,Brown, 2, 3
Adam,Brown, 5, 6
Thom,Bow, 1, 5

所有行的列数不一定相同。但是,前两列始终存在。

1 个答案:

答案 0 :(得分:2)

awk是你的朋友:

awk -F\, -v k=2 'a[$1, $2]++<k+0' file

<强>结果

John,Smith, 2, 3
John,Smith, 2, 3
Adam,Brown, 2, 3
Adam,Brown, 5, 6
Thom,Bow, 1, 5

<强>解释

传递最大迭代次数:-v k=2

我们使用关联array,它的由行$1, $2的前两个字段组成,这些字段由逗号字符:-F\,

每次找到相同的密钥时,$1, $2密钥的数组的值增加a[$1, $2]++

awk中如果表达式满足条件默认操作是打印当前行/行,那么我们只会显示一个已创建密钥的最大k个位置<k+0

注意+0中的k+0是一种强制k变量中的整数值的安全机制。

按姓氏分组的未分类文件示例

$ cat file
John,Smith, 2, 3
Adam,Brown, 2, 3
John,Smith, 2, 3
Thom,Bow, 1, 5
Adam,Brown, 5, 6
Adam,Brown, 1, 1
John,Smith, 1, 4
John,Smith, 6, 2

使用按第二个字段排序:

$ awk -F\, -v k=2 'a[$1, $2]++<k+0' file|sort -r -t, -k 2
John,Smith, 2, 3
John,Smith, 2, 3
Adam,Brown, 5, 6
Adam,Brown, 2, 3
Thom,Bow, 1, 5