2009-04-19 25 views
0

我運行Vim的搜索模式無法搜索重複的句子在Vim的

^(\1) (\2) 

我試圖找到這兩個第一詞在我的.vimrc同一線失敗之後。

如何在Vim中搜索這些行? [第一個答案後編輯]

我找到了方便的工具

:sort u 

我如何比較我的第一個版本,並命令後出現的後續版本?

回答

2

你是一個小曖昧。

  • 如果您想查找第二個單詞是第一個單詞重複的行,例如,通過他們的前兩個字,例如
     
        /^\s*\(\w\+\)\s\+\1 
    
    的第一個字是由\(\w\+\)抓獲,並通過反向引用\1

  • 再次匹配。如果你想組線:

     
        dog dog this line 
        dog cat not this line 
        cat cat this line 
        cat dog not this line 
    
    然後使用以下的正則表達式
     
        a a is the first line in group 'a a' 
        a b is the first line in group 'a b' 
        a b is the second line in group 'a b' 
        -------------nogroup--------------- 
        a b is the third line in group 'a b' 
        b b is the first line in group 'b b' 
        a b is the fourth line in group 'a b' 
         b b is the second line in group 'b b' 
    
    然後:sort是你的朋友。然而,如果你只運行:sort,你會得到:
     
         b b is the second line in group 'b b' 
        -------------nogroup--------------- 
        a a is the first line in group 'a a' 
        a b is the first line in group 'a b' 
        a b is the fourth line in group 'a b' 
        a b is the second line in group 'a b' 
        a b is the third line in group 'a b' 
        b b is the first line in group 'b b' 
    
    請注意組「ab」中的第四行如何放置在第一行之後,並且組 'bb'中的第二行首先被放置,因爲前導空格。這是因爲默認情況下,:sort, 使用整個行。爲了得到它由前兩個單詞只排序,以及以其他方式保持 順序,使用:sort /^\s*\zs\w\+\s\+\w\+/ r
     
        -------------nogroup--------------- 
        a a is the first line in group 'a a' 
        a b is the first line in group 'a b' 
        a b is the second line in group 'a b' 
        a b is the third line in group 'a b' 
        a b is the fourth line in group 'a b' 
        b b is the first line in group 'b b' 
         b b is the second line in group 'b b' 
    
    ^\s*\zs告訴它忽略前導空格和\w\+\s\+\w\+告訴它使用的第一個 兩個詞作爲一種關鍵的。 r選項告訴:sort使用給定的 模式作爲排序關鍵字。欲瞭解更多信息,請參閱:help :sort

    如果你想看看有什麼變化,有一些我能想到的兩種策略,以幫助您:

    • 你可以挽救你的文件,該行進行排序,然後副本保存爲一個不同的名稱,然後使用vim的內置差異功能來比較兩者:
       
      :w         "save your file 
      :sort /^\s*\zs\w\+\s\+\w\+/ r  "sort it by the first two words 
      :w %.sorted      "save the sorted version in a new file with a .sorted extension 
      :undo        "undo your changes to the original 
      :vs %.sorted      "open the sorted version in a new window 
      :windo diffthis     "compare the two versions 
      
      但是,這可能不會給你非常有用的反饋。

    • 什麼可能會給你更多的有用的反饋是對排序之前,而不是插入的行號,這樣你就可以看到你的原始文件的行號去哪裏。爲此,請嘗試以下操作:
       
      :%s/^/\=line('.') . ' ' 
      :sort /^\d\+\s*\zs\w\+\s\+\w\+/ r 
      
      %s/^/\=line('.') . ' '將行號插入每行的開頭。然後,這種排序(略微修改爲忽略行號)完成它的事情。對於上面的例子,這 生產:
       
      4 -------------nogroup--------------- 
      1 a a is the first line in group 'a a' 
      2 a b is the first line in group 'a b' 
      3 a b is the second line in group 'a b' 
      5 a b is the third line in group 'a b' 
      7 a b is the fourth line in group 'a b' 
      6 b b is the first line in group 'b b' 
      8  b b is the second line in group 'b b' 
      
      所以,現在你知道從哪裏冒出什麼線。
1

您是不是要找:removing duplicate lines

+0

我不是那個意思完全一樣。我想找到兩行第一個單詞相同的行。 – 2009-04-19 11:32:38

1

我無法找出這短短的VIM風格的解決方案。這就是爲什麼這裏是vim腳本。

function! s:escape(line) 
    return escape(a:line, '[]*') 
endfunction 

function! s:highlight_similar(pattern, extraction) 
    let sorted = sort(getline(1, '$')) 
    let matched_lines = {} 

    let pattern = '^\s*\(\w\+\)\s\+\(\w\+\).*$' 
    let previous_part = '' 
    let previous_line = '' 

    for i in range(0, line('$') - 1) 
     let line = sorted[i] 
     if line !~ a:pattern 
      continue 
     endif 
     let part = substitute(line, a:pattern, a:extraction, '') 
     if empty(part) 
      continue 
     endif 
     if part == previous_part 
      let matched_lines[s:escape(line)] = i 
      let matched_lines[s:escape(previous_line)] = i 
     else 
      let previous_part = part 
      let previous_line = line 
     endif 
    endfor 
    let @/ = join(keys(matched_lines), '\|') 
endfunction 

和命令的定義,應該是在同一個文件

command! -nargs=0 HighlightTwoWords 
     \call <SID>highlight_similar('^\s*\(\w\+\)\s\+\(\w\+\).*$', '\1 \2') 
command! -nargs=0 HighlightTwoRows 
     \call <SID>highlight_similar('^\s*\(.*\)\s*$', '\1') 

並採用「HighlightTwoWords」命令,你將能夠使用「n」和「N」通過線移動後,那麼你感興趣。或者使用'hls [earch]'命令可以突出顯示這些行。

+0

我有兩條線。 $ 1:設置歷史= 1000「的評論和$ 2:。設置歷史= 1000它無法找到這些重複 – 2009-04-19 12:05:49

+0

你可能只是需要改變\ W公司於[^ \ S]如果你的‘單詞’可以由除了空格什麼(不知道怎麼會在VIM被格式化,但我敢肯定有人可以幫忙) – cmptrgeekken 2009-04-19 14:12:56

+0

@cmptrgeekken:首先評論是答案的第一個版本的這個版本處理事情 – 2009-04-19 16:22:48

1

您的意思是:找到前兩個單詞相同的任何行嗎?

試試這個:

/^(\ w +)\ 1

或者更一般

/^(\ w +)\ S \ 1