2015-09-09 73 views
1

我想知道如何消除多个文件中的重复行。我用这个命令来获得重复的行,但它只能说明我在常见的线:使用awk或sed消除多个文件中的重复行

sort *.txt | uniq -d | fgrep -f - *.txt | sort -t : -k 2 

举例来说,如果我有以下文件:

FILE1.TXT:

AAA 
BBB 
CCC 

FILE2.TXT:

AAA 
EEE 
FFF 

file3.txt:

BBB 
ZZZ 
... 

file20.txt:

AAA 
BBB 
TTT 

我想有作为的结果:

FILE1.TXT:

AAA 
BBB 
CCC 

FILE2.TXT:

EEE 
FFF 

文件3 .txt:

ZZZ 
.... 

file20.txt:

TTT 
+1

你能提供你的意思是“消除重复的行从多个文件”是什么一个简洁的例子:是每个单独的文件里面有重复,是不同文件中的重复行,等等,你是否想要消除重复行的每一个出现,或每一次出现,但除了一个?在这种情况下,如果重复出现在多个文件中,您想保留哪一个文件? – Benoit

+0

我编辑我的问题 – malmo

回答

4

不要使用uniq-d标志。这将只显示重复的行。

uniq --help

-d, --repeated  only print duplicate lines, one for each group 

相反,使用uniq不带任何参数:

sort *.txt | uniq | ... 

,或者更简单,sort可以uniquify为您提供:

sort -u *.txt | ... 
1
awk '!Line[$0]++' *.txt 

只打印一次任意字符串,即使目前在几个文件中和/或在同一个文件

新OP约束的增加(每个文件输出)

awk '!Line[$0]++ > (FILENAME ".new")' *.txt 

重定向awk中的限制,输出从FileX.txt重定向到FileX.txt.new。原始文件可以使用一些变化(不直接要求的目的)

+0

也将保持顺序,不需要排序。 – karakfa

+0

没错,因为OP使用排序(并且易于输出)。它使用更多的memroy,通过数组索引在内存中保留行,其中multipipe可以在需要时使用临时文件。 – NeronLeVelu

1

你可以在Vim中做到这一点:打开gvim(例如)与所有文件作为参数
然后

  1. 将以下代码复制到剪贴板

    let g:duplicate_finder={} 
    function Remove_duplicates() 
        " Get the buffer lines 
        let buf_lines = getline(1, '$') 
        " Reduce the buffer to one empty line 
        execute '%d _' 
        " Append to the buffer only lines never encountered before 
        for cur_buf_line in buf_lines 
         if !has_key(g:duplicate_finder, cur_buf_line) 
          call append(line('$'), cur_buf_line) 
          let g:duplicate_finder[cur_buf_line] = '1' 
         endif 
        endfor 
        " Delete first line from the buffer 
        execute '1d _' 
    endfunction 
    argdo call Remove_duplicates() 
    

  2. 在gVim的窗口中,键入:@+回报运行代码。

另一种方法是:

  1. 保存以上到名为remove_duplicates.vim文件中的代码,并
  2. 在gVim的窗口中键入:source /path/to/remove_duplicates.vim返回

为了保存所有的缓冲区,然后运行:xa回报