Vim Tips Wiki
(Move categories to tip template)
(Remove html character entities)
Line 25: Line 25:
 
<pre>
 
<pre>
 
g/^\(.*\)$\n\1$/d
 
g/^\(.*\)$\n\1$/d
g/\%(^\1$\n\)\@&lt;=\(.*\)$/d
+
g/\%(^\1$\n\)\@<=\(.*\)$/d
 
</pre>
 
</pre>
   
Line 31: Line 31:
   
 
<pre>
 
<pre>
g//d &lt;-- Delete the lines matching the regexp
+
g//d <-- Delete the lines matching the regexp
\@&lt;= &lt;-- If the bit following matches, make sure the bit preceding this symbol directly precedes the match
+
\@<= <-- If the bit following matches, make sure the bit preceding this symbol directly precedes the match
\(.*\)$ &lt;-- Match the line into subst register 1
+
\(.*\)$ <-- Match the line into subst register 1
\%( ) &lt;--- Group without placing in a subst register.
+
\%( ) <--- Group without placing in a subst register.
^\1$\n &lt;--- Match subst register 1 followed by end of line and the new line between the 2 lines
+
^\1$\n <--- Match subst register 1 followed by end of line and the new line between the 2 lines
 
</pre>
 
</pre>
   
Line 43: Line 43:
   
 
<pre>
 
<pre>
g/\%(^\1\&gt;.*$\n\)\@&lt;=\(\k\+\).*$/d
+
g/\%(^\1\>.*$\n\)\@<=\(\k\+\).*$/d
 
</pre>
 
</pre>
   
Line 55: Line 55:
   
 
<pre>
 
<pre>
:nno \d1 :g/^/m0&lt;CR&gt;:g/^\(.*\)\n\_.*\%(^\1$\)/d&lt;CR&gt;:g/^/m0&lt;CR&gt;
+
:nno \d1 :g/^/m0<CR>:g/^\(.*\)\n\_.*\%(^\1$\)/d<CR>:g/^/m0<CR>
 
</pre>
 
</pre>
   
Line 61: Line 61:
   
 
<pre>
 
<pre>
:nno \d2 :g/^/kl\|if search('^'.escape(getline('.'),'\.*[]^$/').'$','bW')\|'ld&lt;CR&gt;
+
:nno \d2 :g/^/kl\|if search('^'.escape(getline('.'),'\.*[]^$/').'$','bW')\|'ld<CR>
 
</pre>
 
</pre>
   

Revision as of 09:07, 29 September 2008

Duplicate tip

This tip is very similar to the following:

These tips need to be merged – see the merge guidelines.

Tip 648 Printable Monobook Previous Next

created February 1, 2004 · complexity intermediate · author Michael Geddes · version 6.0


In Vim 7.0 and later, the following command will sort all lines and remove duplicates:

:sort u

If you need more control, here are some alternatives.

There are two versions, the first leaves only the last line, the second leaves only the first line.

g/^\(.*\)$\n\1$/d
g/\%(^\1$\n\)\@<=\(.*\)$/d

Breakdown of the second version:

g//d <-- Delete the lines matching the regexp
\@<= <-- If the bit following matches, make sure the bit preceding this symbol directly precedes the match
\(.*\)$ <-- Match the line into subst register 1
\%( ) <--- Group without placing in a subst register.
^\1$\n <--- Match subst register 1 followed by end of line and the new line between the 2 lines

In this simple format (matching the whole line), it's not going to make much difference, but it will start to matter if you want to do stuff like match the first word only

This does a uniq on the first word in the line, and deletes all but the first line:

g/\%(^\1\>.*$\n\)\@<=\(\k\+\).*$/d

See also

  • VimTip1148 for a way to apply uniq on elements from a VimL List (and not text lines)

Comments

Here are some more Vim-native ways for removing duplicate lines. This time they don't have to be adjacent. Line order is preserved.

This one can be a bit slow.

:nno \d1 :g/^/m0<CR>:g/^\(.*\)\n\_.*\%(^\1$\)/d<CR>:g/^/m0<CR>

This is faster. Uses mark l.

:nno \d2 :g/^/kl\|if search('^'.escape(getline('.'),'\.*[]^$/').'$','bW')\|'ld<CR>