查找文件中所有非唯一行

查找文件中所有非唯一行

我正在尝试使用 uniq 查找文件中的所有非唯一行。我所说的非唯一是指我在上一行中已经看到的任何行。我认为“-D”选项可以做到这一点:

-D     print all duplicate lines

但它不只是打印重复的行,而是打印全部当有多条线路时。我只想打印一行的第二份和后续副本。

我怎样才能做到这一点?

答案1

您需要 GNU 版本的小写 -d 选项。

# printf "a\na\na\nb\nb\nc\n" | uniq -d
a
b

答案2

使用 GNU 或 ast-open 实现uniq

uniq -D -u < input

-D本身是非标准的),但请注意,这是它删除的最后一个重复项,而不是第一个(如果您还使用-i,-w或,这会有所不同-f

可移植的是,您始终可以使用awk

awk 'NR > 1 && $0 "" == previous ""; {previous = $0}' < input

(与 is 的连接强制""进行字符串比较,即使操作数看起来像数字)

仅比较前 9 个字符(请注意,这-w也是一个 GNU 扩展,并且(当前)适用于字节,而不是字符(尽管其文档是这么说的)):

awk '{current = substr($0, 1, 9)}
     NR > 1 && current == previous
     {previous = current}' < input

""(在这种情况下不需要连接,因为substr()返回一个字符串)。

在 UTF-8 语言环境中,在输出上

printf '%s\n' StéphaneChazelas StéphaneUNIX StéphaneUnix

StéphaneUnix按预期给出 while uniq -w9 -D -u(使用 GNU uniq)给出StéphaneChazelas并且StéphaneUNIXStéphane原样给出 8 个字符,但 UTF-8 中的 9 个字节,而 ast-openuniq仅给出 StéphaneUNIX (awk跳过第一次出现,uniq删除最后一次出现)。

使用awk,您还可以报告所有重复行,即使它们不与以下内容相邻:

 awk 'seen[$0]++' < input

(请注意,它将内存中的所有唯一行存储在哈希表中)。

或者只考虑前 9 个字符:

 awk 'seen[substr($0, 1, 9)]++' < input

答案3

解决方案是使用-c uniq ,然后删除你想要的内容

e444$ (   echo a ; echo a ; echo b ; echo d ; echo d ; echo e )  | uniq -c
  2 a
  1 b
  2 d
  1 e 

ad 是重复的 和be 双重的

e444$ (   echo a ; echo a ; echo b ; echo d ; echo d ; echo e )  | uniq -c  \             
              | sed -E '/^ *1 .$/d;s/^ *[0-9]+ //'

表达式的解释sed

/^ *1 .$/d将删除所有唯一行

s/^ *[0-9]+ // 将删除计数器

相关内容