我有一个这样的.csv文件:
stack2@domain.example,2009-11-27 01:05:47.893000000,domain.example,127.0.0.1
overflow@domain2.example,2009-11-27 00:58:29.793000000,domain2.example,255.255.255.0
overflow@domain2.example,2009-11-27 00:58:29.646465785,domain2.example,256.255.255.0
...
字符串
我必须从文件中删除重复的电子邮件(整行)(即上面例子中包含overflow@domain2.example
的行之一)。如何仅在字段1上使用uniq
(用逗号分隔)?根据man
,uniq
没有列选项。
我尝试了sort | uniq
,但它不工作。
9条答案
按热度按时间k5hmc34c1#
字符串
-u
表示唯一-t,
所以逗号是分隔符-k1,1
用于关键字段1试验结果:
型
cwxwcias2#
字符串
-F
设置字段分隔符。$1
是第一个字段。_[val]
在hash_
(一个常规变量)中查找val
。++
递增,并返回旧值。!
返回逻辑非。b4lqfgs43#
要考虑多列。
根据第1列和第3列排序并给予唯一列表:
字符串
-t :
冒号是分隔符-k 1,1 -k 3,3
基于列1和列3ahy6op9u4#
如果要使用
uniq
:。<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
个给出:
kulphzqa5#
如果你想保留你可以使用的最后一个副本
字符串
这是我的要求
在这里
tac
将逐行反转文件3df52oht6#
这是一个非常漂亮的方法。
首先格式化内容,以便比较唯一性的列具有固定宽度。一种方法是使用awk printf和字段/列宽度说明符(“%15s”)。
现在,uniq的-f和-w选项可以用来跳过前面的字段/列,并指定比较宽度(列宽度)。
这里有三个例子。
在第一个例子中…
1)暂时使感兴趣的列具有大于或等于字段的最大宽度的固定宽度。
2)使用-f uniq选项跳过前面的列,并使用-w uniq选项将宽度限制为tmp_fixed_width。
3)删除列中的尾随空格以“恢复”其宽度(假设之前没有尾随空格)。
字符串
在第二个例子中…
创建新的uniq列1.然后在应用uniq过滤器后将其移除。
型
第三个示例与第二个示例相同,但适用于多列。
型
2ekbmq327#
awk
CLI,其行为类似于不带sort
的uniq
,但仅捕获连续的重复到目前为止,大多数其他答案都给出了删除重复项的方法,即使它们不是连续的。
这样做的问题是,它需要首先排序或在内存中存储潜在的巨大Map,这对于大型输入文件可能很慢/不可行。
因此,对于这些情况,这里有一个
awk
解决方案,像uniq
一样,只捕获出现在连续行上的重复项。例如,要删除第一列上的所有连续重复项,我们可以使用$1
,如下所示:字符串
例如,考虑输入文件:
型
输出将是:
型
这里:
a 1
列被删除,因为前一个a 0
行具有重复的第一列a
a 0
列,因为b 0
行破坏了连续性awk
脚本的工作原理很简单,它将前一行的列值存储在last
值中,并将当前值与之进行比较,如果不同则跳过。如果你知道你的输入数据有很多无用的连续重复,并且想在做任何更昂贵的排序处理之前清理一下,这种只连续的方法可能很有用。
如果你真的需要删除非连续的重复项,更健壮的解决方案通常是使用像SQLite这样的关系数据库,例如:how can I delete duplicates in SQLite?
快速Python脚本,用于删除最后N行中出现的重复内容
如果你需要更多的灵活性,但仍然不想支付完整的排序:
统一
型
此脚本查找前面
-n
行上的重复项,并且可以用于清除具有某种周期性模式的数据,这些模式阻止uniq
对其执行太多操作。-k
选择列。例如,考虑输入文件:单一测试
然后:
型
给出:
例如,第二个
1 a
看到第一个1 a
三行后,并跳过它作为-n3
的结果。需要考虑的一些内置
uniq
选项虽然
uniq
没有一个很好的“只考虑第N”列,但它确实有一些标志,可以解决某些更受限制的情况,从man uniq
:-f,-跳过字段=N:避免比较前N个字段
-s,--skip-chars=N:避免比较前N个字符
-w,--check-chars=N:每行比较不超过N个字符
字段是一串空格(通常是空格和/或TAB),然后是非空字符。在字符之前跳过字段。
如果有人将类似于
--check-chars
的--check-fields
修补到它,那么我们就完成了--skip-fields N-1 --check-fields 1
。然而,它已经适用于第一字段的特定情况。在Ubuntu 23.04上测试。
ckx4rj1h8#
首先使用
sort
对文件进行排序,然后可以应用uniq
。它似乎可以很好地对文件进行排序:
字符串
你也可以使用一些AWK魔法:
型
1yjd4xko9#
好吧,比用awk隔离列更简单,如果你需要删除给定文件中具有特定值的所有内容,为什么不直接使用grep -v:
例如,删除第二行中具有值“col 2”的所有内容:col1、col2、col3、col4
字符串
如果这还不够好,因为一些行可能会被不正确地剥离,因为可能会在不同的列中显示匹配的值,你可以这样做:
awk来隔离有问题的列:例如,在
型
-F将字段分隔为“,”,$2表示列2,后跟一些自定义分隔符,然后是整行。然后,您可以通过删除以违规值 * 开始 * 的行进行过滤:
型
然后去掉分隔符前的内容:
型
(note- sed命令是草率的,因为它不包括转义值。另外,sed模式实际上应该类似于“[^|]+”(即任何不是分隔符的内容)。但希望这是足够清楚的。