No edit summary |
(highlighted "keep only unique lines" - it was easy to assume the 'u' was part of what 'sort' needed to operate) Tag: Visual edit |
||
(41 intermediate revisions by 19 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{TipImported |
||
− | {{review}} |
||
− | {{Tip |
||
|id=1166 |
|id=1166 |
||
+ | |previous=1164 |
||
− | |title=Sort lines - easy use of existing vim capability |
||
+ | |next=1167 |
||
− | |created= |
+ | |created=2006 |
|complexity=basic |
|complexity=basic |
||
− | |author=Robert Stovall |
+ | |author=Robert Stovall |
− | |version= |
+ | |version=7.0 |
|rating=29/17 |
|rating=29/17 |
||
+ | |category1= |
||
− | |text= |
||
+ | |category2= |
||
− | This is just a reminder of how to take advantage of existing VIM capability. I had not needed to sort before and took a few minutes to find a good example. |
||
⚫ | |||
+ | Vim has a very powerful built-in sort utility, or it can interface with an external one. In order to '''''keep only unique lines''''' in Vim, you would: |
||
+ | <pre> |
||
⚫ | |||
+ | </pre> |
||
⚫ | |||
+ | You could create a range in advance, such as <code>'a,.</code> (from mark 'a' to the current line) or you could create one on-the-fly using visual selection by pressing ':' in visual mode, after selecting the text you wish to sort, to get a range of <code>'<,'></code> on the command line. |
||
− | Sort lines in vim using blocks: |
||
+ | If you like using an external sort utility instead, you can do it just as easily. For example, Unix sort, removing duplicate lines: |
||
+ | <pre> |
||
⚫ | |||
+ | </pre> |
||
+ | Many other systems also have an external sort utility, but the options and capabilities will differ. It is probably better to use the built-in Vim sort unless you are looking for a specific feature of the external sort (or using an old Vim without the <code>:sort</code> command). |
||
⚫ | |||
+ | ==Examples== |
||
+ | ===Sort in reverse=== |
||
+ | <pre>:%sort!</pre> |
||
+ | ===Sort, removing duplicate lines=== |
||
+ | <pre>:%sort u</pre> |
||
+ | ===Sort using the external Unix sort utility, respecting month-name order=== |
||
⚫ | |||
+ | <pre>:%!sort -M</pre> |
||
+ | ("respecting month-name order" means January < February < ... < December) |
||
+ | ===Numeric sort=== |
||
+ | <pre>:sort n</pre> |
||
+ | (this way, 100 doesn't precede 20 in the sort) |
||
+ | ===Sort subsections independently, in this example sort numbers between "start" and "end" markers=== |
||
+ | <pre>:g/start/+1,/end/-1 sort n</pre> |
||
+ | === Sort only specific lines using ranges === |
||
− | Key strokes: |
||
+ | sort lines 296 to 349, inclusive |
||
+ | :296,349sort |
||
+ | === Sort by pattern === |
||
+ | When working with Javascript ES6, it may be useful to sort your imports |
||
+ | <pre> |
||
+ | import './ProjectTemplateEditModal.scss'; |
||
+ | import * as _ from "lodash"; |
||
+ | import Moment from 'moment'; |
||
+ | import React from 'react'; |
||
+ | import { Button, Col, Modal, Row, Label } from 'react-bootstrap'; |
||
+ | import { CurrencyControl } from '../../Core/Components/Controls'; |
||
+ | import { DynamicModalMixin } from '../../Core/Components/Modals'; |
||
+ | import { ProjectTemplateStore } from '../Stores/ProjectTemplateStore'; |
||
+ | import { StoreBinder } from '../../Core/Utils/StoreBinder'; |
||
+ | import { TextAreaControl } from '../../Core/Components/Controls/TextAreaControl'; |
||
+ | import { TextBoxControl } from '../../Core/Components/Controls/TextBoxControl'; |
||
+ | import { TooltipWrapper } from '../../Core/Components/Tooltips/TooltipWrapper'; |
||
+ | import { withRouter } from 'react-router'; |
||
+ | </pre> |
||
+ | |||
+ | It is possible to pass a regex expression to sort. Any lines that do not match the expression will be sorted normally, while lines that do match will be sorted on the text that *follows* the expression. <pre>:{range}sort /\/[A-z]/</pre> This will organize your imports relative to the "package" they are related to: |
||
+ | <pre> |
||
− | 1) Place cursor at first line of range to be sorted. |
||
+ | import * as _ from "lodash"; |
||
+ | import Moment from 'moment'; |
||
+ | import React from 'react'; |
||
+ | import { Button, Col, Modal, Row, Label } from 'react-bootstrap'; |
||
+ | import { withRouter } from 'react-router'; |
||
+ | import { CurrencyControl } from '../../Core/Components/Controls'; |
||
+ | import { TextAreaControl } from '../../Core/Components/Controls/TextAreaControl'; |
||
+ | import { TextBoxControl } from '../../Core/Components/Controls/TextBoxControl'; |
||
+ | import { DynamicModalMixin } from '../../Core/Components/Modals'; |
||
+ | import { TooltipWrapper } from '../../Core/Components/Tooltips/TooltipWrapper'; |
||
+ | import { StoreBinder } from '../../Core/Utils/StoreBinder'; |
||
+ | import './ProjectTemplateEditModal.scss'; |
||
+ | import { ProjectTemplateStore } from '../Stores/ProjectTemplateStore'; |
||
+ | </pre> |
||
+ | |||
+ | You can also sort on text that *matches* the regex by including the 'r' flag, for example: <pre>:{range}sort /\/[A-z]/ r</pre> |
||
+ | ==See also== |
||
− | 2) Use marker (ma) to mark starting point |
||
+ | *[[VimTip374|374 Use filter commands to process text]] |
||
+ | *[[VimTip588|588 How to sort using visual blocks]] |
||
+ | *[[VimTip758|758 Search and sort by selection]] |
||
+ | *[[VimTip800|800 Sorting lines in a file based on the number of words in each line]] |
||
+ | *[[VimTip923|923 Sort lines by a specified word number]] |
||
+ | *[[VimTip667|667 Working with CSV files]] sort by CSV field |
||
+ | *[[VimTip128|128 Use Unix command-line tools in Windows]] links to download GNU sort for Windows |
||
+ | *[[VimTip648|648 Uniq - Removing duplicate lines]] techniques to remove duplicate lines |
||
+ | ==References== |
||
− | 3) Go to last line of range to be sorted |
||
+ | *{{help|:sort}} |
||
⚫ | |||
− | 4) Issue command from marker (a) to here as follows: |
||
+ | {{Todo}} |
||
⚫ | |||
+ | *Probably need some general <code>:sort</code> command info. |
||
+ | *Give examples of numeric sort and using regex sort. |
||
+ | *Clean up my "see also" list. It's useful now for a comprehensive list of related tips, some of which need work. At least should add a note on point of tip. |
||
+ | *If we're going to mention an external sort tool, we may as well include the following with a brief explanation. Vim could do this, but only with a complex regex. Or perhaps better, mention it in [[VimTip374]] or [[VimTip923]] in "see also". <code>-k2</code> sorts on the second field (word by default). |
||
+ | <pre> |
||
⚫ | |||
+ | </pre> |
||
− | |||
− | |||
− | |||
− | |||
− | Hope this little reminder helps. |
||
⚫ | |||
− | |||
⚫ | |||
− | Use "V" and highlight the lines you want (instead of marks), then :!sort. |
||
− | |||
− | '''Anonymous''' |
||
− | , March 9, 2006 7:34 |
||
---- |
---- |
||
+ | This misguided snippet was added recently: |
||
− | Note that for vim <7, this uses the external sort program. |
||
− | This has some consequences: |
||
+ | :delimit the column using some char here I have | symbol as delimiter, once did with that you can use below command to sort specific column use -n if u want to sort numeric and its working on some version of vi and not on ubuntu vi :( |
||
− | - the program must be installed (which it usually is) |
||
− | - options can be passed to it |
||
+ | <pre>/|.*|/ | sort</pre> |
||
− | which means you can do (for example) |
||
− | :!sort -n |
||
− | to sort numerically, |
||
⚫ | |||
− | to sort on the second field, etc |
||
+ | :used to match a patern |.*| used to match words delimited between || and | as piping commend and sort to sort |
||
− | '''Anonymous''' |
||
− | , March 9, 2006 14:21 |
||
− | ---- |
||
− | Just to point out that sort is a *nix utility. windows users will need to get sort.exe from |
||
− | http://www.cygwin.com/ |
||
− | or http://unxutils.sourceforge.net/ |
||
+ | This is wrong and should never work. Here's what it is actually doing: |
||
− | To sort whole file, and delete duplicates |
||
⚫ | |||
+ | <code>/|.*|/</code>: jump to the next line that has two '|' characters in it, anywhere |
||
− | the ! here means access external utility |
||
+ | <code>|</code>: command separator, this lets you start a new command on the current line |
||
+ | <code>sort</code>: do a default sort of the entire buffer |
||
+ | Basically this is the equivalent of typing <code>:%sort</code>. |
||
− | zzapper |
||
− | , March 10, 2006 4:03 |
||
− | ---- |
||
− | Check [http://vimplugin.sf.net/cgi-bin/help?tag={{urlencode:eval-examples}} :help eval-examples] |
||
+ | Now, what you CAN do, is provide a pattern that the <code>:sort</code> command will skip over and ignore at the start of every line while sorting. For example, to sort based only on text after the last '|' character on the line (what I think was intended by the example), you'd do this: |
||
− | It has (as an example) a vim function called :Sort by Robert Webb that doesn't require an external sort utility. |
||
+ | <pre> |
||
− | - Karthick |
||
⚫ | |||
− | |||
+ | </pre> |
||
− | '''Anonymous''' |
||
− | , March 12, 2006 19:37 |
||
− | ---- |
||
− | See also [[VimTip305]], [[VimTip374]], and [[VimTip588]]. |
||
− | |||
− | mfo--AT--sympatico.ca |
||
− | , March 13, 2006 10:53 |
||
− | ---- |
||
− | To remove duplicate lines from a sorted list (make each line unique): |
||
− | |||
− | :%s/^\(.*\)\(\n\1\n\)\+/\1/g |
||
− | |||
− | |||
− | org.vim--AT--pooryorick.com |
||
− | , July 14, 2006 11:20 |
||
− | ---- |
||
− | <!-- parsed by vimtips.py in 1.304864 seconds--> |
||
− | |||
− | to remove duplicates from a sorted list use uniq is simpler: |
||
− | |||
− | :%!sort|uniq |
||
− | |||
− | is a binary installed almost everywhere |
||
− | ---- |
Revision as of 04:16, 7 May 2020
created 2006 · complexity basic · author Robert Stovall · version 7.0
Vim has a very powerful built-in sort utility, or it can interface with an external one. In order to keep only unique lines in Vim, you would:
:{range}sort u
Yes, it's that simple.
You could create a range in advance, such as 'a,.
(from mark 'a' to the current line) or you could create one on-the-fly using visual selection by pressing ':' in visual mode, after selecting the text you wish to sort, to get a range of '<,'>
on the command line.
If you like using an external sort utility instead, you can do it just as easily. For example, Unix sort, removing duplicate lines:
:{range}!sort -u
Many other systems also have an external sort utility, but the options and capabilities will differ. It is probably better to use the built-in Vim sort unless you are looking for a specific feature of the external sort (or using an old Vim without the :sort
command).
Examples
Sort in reverse
:%sort!
Sort, removing duplicate lines
:%sort u
Sort using the external Unix sort utility, respecting month-name order
:%!sort -M
("respecting month-name order" means January < February < ... < December)
Numeric sort
:sort n
(this way, 100 doesn't precede 20 in the sort)
Sort subsections independently, in this example sort numbers between "start" and "end" markers
:g/start/+1,/end/-1 sort n
Sort only specific lines using ranges
sort lines 296 to 349, inclusive
:296,349sort
Sort by pattern
When working with Javascript ES6, it may be useful to sort your imports
import './ProjectTemplateEditModal.scss'; import * as _ from "lodash"; import Moment from 'moment'; import React from 'react'; import { Button, Col, Modal, Row, Label } from 'react-bootstrap'; import { CurrencyControl } from '../../Core/Components/Controls'; import { DynamicModalMixin } from '../../Core/Components/Modals'; import { ProjectTemplateStore } from '../Stores/ProjectTemplateStore'; import { StoreBinder } from '../../Core/Utils/StoreBinder'; import { TextAreaControl } from '../../Core/Components/Controls/TextAreaControl'; import { TextBoxControl } from '../../Core/Components/Controls/TextBoxControl'; import { TooltipWrapper } from '../../Core/Components/Tooltips/TooltipWrapper'; import { withRouter } from 'react-router';
It is possible to pass a regex expression to sort. Any lines that do not match the expression will be sorted normally, while lines that do match will be sorted on the text that *follows* the expression.
:{range}sort /\/[A-z]/
This will organize your imports relative to the "package" they are related to:
import * as _ from "lodash"; import Moment from 'moment'; import React from 'react'; import { Button, Col, Modal, Row, Label } from 'react-bootstrap'; import { withRouter } from 'react-router'; import { CurrencyControl } from '../../Core/Components/Controls'; import { TextAreaControl } from '../../Core/Components/Controls/TextAreaControl'; import { TextBoxControl } from '../../Core/Components/Controls/TextBoxControl'; import { DynamicModalMixin } from '../../Core/Components/Modals'; import { TooltipWrapper } from '../../Core/Components/Tooltips/TooltipWrapper'; import { StoreBinder } from '../../Core/Utils/StoreBinder'; import './ProjectTemplateEditModal.scss'; import { ProjectTemplateStore } from '../Stores/ProjectTemplateStore';
You can also sort on text that *matches* the regex by including the 'r' flag, for example:
:{range}sort /\/[A-z]/ r
See also
- 374 Use filter commands to process text
- 588 How to sort using visual blocks
- 758 Search and sort by selection
- 800 Sorting lines in a file based on the number of words in each line
- 923 Sort lines by a specified word number
- 667 Working with CSV files sort by CSV field
- 128 Use Unix command-line tools in Windows links to download GNU sort for Windows
- 648 Uniq - Removing duplicate lines techniques to remove duplicate lines
References
Comments
TO DO
- Probably need some general
:sort
command info. - Give examples of numeric sort and using regex sort.
- Clean up my "see also" list. It's useful now for a comprehensive list of related tips, some of which need work. At least should add a note on point of tip.
- If we're going to mention an external sort tool, we may as well include the following with a brief explanation. Vim could do this, but only with a complex regex. Or perhaps better, mention it in VimTip374 or VimTip923 in "see also".
-k2
sorts on the second field (word by default).
:!sort -k2
This misguided snippet was added recently:
- delimit the column using some char here I have | symbol as delimiter, once did with that you can use below command to sort specific column use -n if u want to sort numeric and its working on some version of vi and not on ubuntu vi :(
/|.*|/ | sort
- used to match a patern |.*| used to match words delimited between || and | as piping commend and sort to sort
This is wrong and should never work. Here's what it is actually doing:
/|.*|/
: jump to the next line that has two '|' characters in it, anywhere
|
: command separator, this lets you start a new command on the current line
sort
: do a default sort of the entire buffer
Basically this is the equivalent of typing :%sort
.
Now, what you CAN do, is provide a pattern that the :sort
command will skip over and ignore at the start of every line while sorting. For example, to sort based only on text after the last '|' character on the line (what I think was intended by the example), you'd do this:
:sort /^.*|/