6

为了使用 uniq 命令,您必须先对文件进行排序。

但是在我拥有的文件中,信息的顺序很重要,那么我怎样才能保持文件的原始格式但仍然摆脱重复的内容呢?

4

7 回答 7

10

另一个 awk 版本:

awk '!_[$0]++' infile
于 2009-03-13T15:37:11.847 回答
4

awk将保留第一次出现。与其他答案使用的算法相同:

awk '!($0 in lines) { print $0; lines[$0]; }'

这是一个只需要存储重复行(而不是所有行)的awk

sort file | uniq -d | awk '
   FNR == NR { dups[$0] }
   FNR != NR && (!($0 in dups) || !lines[$0]++)
' - file
于 2009-03-13T15:18:23.797 回答
4

还有“行号,双重排序”方法。

 nl -n ln | sort -u -k 2| sort -k 1n | cut -f 2-
于 2009-03-13T15:41:17.377 回答
1

您可以在文件的排序版本上运行 uniq -d 以查找重复的行,然后运行一些脚本:

if this_line is in duplicate_lines {
    if not i_have_seen[this_line] {
        output this_line
        i_have_seen[this_line] = true
    }
} else {
    output this_line
}
于 2009-03-13T15:15:37.173 回答
1

仅使用 uniq 和 grep:

创建 d.sh:

#!/bin/sh
sort $1 | uniq > $1_uniq
for line in $(cat $1); do
cat $1_uniq | grep -m1 $line >> $1_out
cat $1_uniq | grep -v $line > $1_uniq2
mv $1_uniq2 $1_uniq
done;
rm $1_uniq

例子:

./d.sh infile
于 2009-03-13T16:08:02.867 回答
0

你可以使用一些可怕的 O(n^2) 东西,像这样(伪代码):

file2 = EMPTY_FILE
for each line in file1:
  if not line in file2:
    file2.append(line)

这可能相当慢,尤其是在 Bash 级别实施时。但是,如果您的文件相当短,它可能会工作得很好,并且可以快速实施(not line in file2然后就是grep -v,依此类推)。

否则,您当然可以编写一个专用程序,在内存中使用一些更高级的数据结构来加速它。

于 2009-03-13T15:12:31.423 回答
0
for line in $(sort file1 | uniq ); do
    grep -n -m1 line file >>out
done;

sort -n out

首先进行排序,

对于第一个匹配的每个唯一值 grep (-m1)

并保留行号

按行号对输出进行数字排序(-n)。

然后,您可以使用 sed 或 awk 删除行#

于 2009-03-13T15:21:00.000 回答