我有一个像这样的.csv文件:
stack2@example.com,2009-11-27 01:05:47.893000000,example.net,127.0.0.1
overflow@example.com,2009-11-27 00:58:29.793000000,example.net,255.255.255.0
overflow@example.com,2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...
我必须从文件中删除重复的电子邮件(整行)(即上例中包含overflow@example.com
的一行)。如何仅在字段1上使用uniq
(以逗号分隔)?根据{{1}},man
没有列的选项。
我尝试使用uniq
,但它不起作用。
答案 0 :(得分:283)
sort -u -t, -k1,1 file
-u
表示唯一-t,
所以逗号是分隔符-k1,1
用于关键字段1 测试结果:
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
答案 1 :(得分:86)
awk -F"," '!_[$1]++' file
-F
设置字段分隔符。$1
是第一个字段。_[val]
在哈希val
(常规变量)中查找_
。++
递增,并返回旧值。!
不返回逻辑。答案 2 :(得分:14)
考虑多列。
根据第1列和第3列排序并提供唯一列表:
sort -u -t : -k 1,1 -k 3,3 test.txt
-t :
冒号是分隔符-k 1,1 -k 3,3
基于第1列和第3列答案 3 :(得分:9)
或者如果你想使用uniq:
<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
给出:
1 01:05:47.893000000 2009-11-27 tack2@domain.com
2 00:58:29.793000000 2009-11-27 overflow@domain2.com
1
答案 4 :(得分:4)
如果您想保留最后一个重复项,可以使用
tac a.csv | sort -u -t, -r -k1,1 |tac
这是我的要求
这里
tac
将逐行反转文件
答案 5 :(得分:0)
这是一种非常好的方式。
首先格式化内容,使得要比较的列的唯一性是固定宽度。一种方法是使用带有字段/列宽度说明符(“%15s”)的awk printf。
现在uniq的-f和-w选项可用于跳过前面的字段/列并指定比较宽度(列宽)。
以下是三个例子。
在第一个例子中......
1)暂时使感兴趣的列的宽度大于或等于字段的最大宽度。
2)使用-f uniq选项跳过先前的列,并使用-w uniq选项将宽度限制为tmp_fixed_width。
3)从列中删除尾随空格以“恢复”它的宽度(假设事先没有尾随空格)。
setInterval(function () {
table3.page('next').draw('page');
}, 5000)
在第二个例子中......
创建一个新的uniq列1.然后在应用uniq过滤器后将其删除。
printf "%s" "$str" \
| awk '{ tmp_fixed_width=15; uniq_col=8; w=tmp_fixed_width-length($uniq_col); for (i=0;i<w;i++) { $uniq_col=$uniq_col" "}; printf "%s\n", $0 }' \
| uniq -f 7 -w 15 \
| awk '{ uniq_col=8; gsub(/ */, "", $uniq_col); printf "%s\n", $0 }'
第三个示例与第二个示例相同,但是对于多个列。
printf "%s" "$str" \
| awk '{ uniq_col_1=4; printf "%15s %s\n", uniq_col_1, $0 }' \
| uniq -f 0 -w 15 \
| awk '{ $1=""; gsub(/^ */, "", $0); printf "%s\n", $0 }'
答案 6 :(得分:-2)
嗯,比用awk隔离列更简单,如果你需要删除给定文件的某个值的所有内容,为什么不做grep -v:
e.g。在第二位删除值为“col2”的所有内容 line:col1,col2,col3,col4
grep -v ',col2,' file > file_minus_offending_lines
如果这还不够好,因为某些行可能会因为匹配值显示在不同的列中而被不正确地剥离,您可以执行以下操作:
要隔离有问题的列: 例如
awk -F, '{print $2 "|" $line}'
< - > -F将字段分隔为“,”,$ 2表示第2列,后跟一些自定义分隔符,然后是整行。然后,您可以通过使用有问题的值删除开始的行进行过滤:
awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE
然后在分隔符之前去掉东西:
awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE | sed 's/.*|//g'
(注意 - sed命令很邋因,因为它不包含转义值。而且sed模式应该像“[^ |] +”(即任何不是分隔符)。但希望这很清楚
答案 7 :(得分:-2)
首先使用sort
对文件进行排序,然后您可以应用uniq
。
似乎对文件排序很好:
$ cat test.csv
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
$ sort test.csv
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
$ sort test.csv | uniq
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
你也可以做一些AWK魔术:
$ awk -F, '{ lines[$1] = $0 } END { for (l in lines) print lines[l] }' test.csv
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0