Paste a list. Remove duplicate lines, sort them, drop the blanks, trim the spaces. Paste a list and clean it up: remove duplicate lines, sort lines alphabetically, remove empty lines and trim whitespace. Every rule the page applies is written down next to the box that turns it on, including exactly what counts as a duplicate. Free, no sign up, and nothing you paste is sent anywhere.
Counted before anything is removed.
What the box on the right holds.
Lines in minus lines out.
Nothing to clean yet.
Most list cleaners give you the same five switches and never say what they mean, so you find out
that Apple survived next to apple only after you have pasted the result
somewhere. Here is the whole specification. It is short on purpose.
Always this order, whichever boxes are ticked:
New York keeps its double space.
The order is what makes the switches work together rather than fight. Trimming before the duplicate
check is what lets apple and apple be recognised as the same entry.
Removing blanks before the duplicate check is what makes twelve blank lines disappear instead of
collapsing into one surviving blank line.
| Boxes ticked | Two lines are the same when… | Apple vs apple |
|---|---|---|
| Neither | Every character matches exactly, capitals and edge spaces included | Different |
| Trim whitespace | Every character matches after both ends are stripped | Different |
| Ignore case | The lowercased text matches, edge spaces still count | Different |
| Both | The lowercased text matches after both ends are stripped | Duplicate |
\r\n and a bare \r are both read as one line break, so a list copied out of Windows behaves the same as one copied out of anywhere else. The result is always joined back with \n.
Lines are compared character by character in code order, which is the ordering you get from the
JavaScript < operator, and it is not dictionary order. Every capital letter sits
below every lowercase letter, and digits sit below both.
With Ignore case off, [Banana, apple, Cherry] sorts to
Banana, Cherry, apple. Tick Ignore case and the same list sorts to
apple, Banana, Cherry, which is what most people mean by alphabetical.
The sort is stable, so two lines that compare equal stay in the order you pasted them.
Text arrives spelled in more than one way, and this page never quietly respells it. The rules below are the consequences of that, written out so a surprising result is at least a documented one.
| Case | What the page does | Why |
|---|---|---|
The same accented word spelled two ways, café as one é versus e plus a combining accent |
Two different lines. Not duplicates, and they sort apart | No Unicode normalisation is applied. Normalising would edit characters you did not ask to have edited, and the two spellings really are different text |
| A zero width space or a zero width joiner inside a line | An ordinary character. It is never trimmed, a line holding only zero width characters is not empty, and it makes the line different from its clean twin | Those characters are not whitespace. Dropping them would be a silent edit, and a line that looks blank but is not is worth seeing |
| A non breaking space, an ideographic space, or a byte order mark at the end of a line | Trimmed, same as an ordinary space | Trim uses the whitespace set the language itself defines, which includes all three |
Turkish İ and ı with Ignore case on |
İ is not the same as I, and ı is not the same as i |
Lowercasing is done without a locale, for the same reason sorting is. A Turkish rule applied to an English list would be just as wrong the other way round |
Emoji, and characters above U+FFFF generally |
Kept whole, and sorted by code unit, which places them before the last slice of ordinary characters rather than after everything | Code order is the ordering of the underlying storage units, and those characters are stored as a pair. The ordering is at least exactly reproducible |
| A right to left override left in a pasted line | Kept as a character. It may reorder how the line looks, but comparison and sorting use the stored order | Removing it would change the text; ignoring how it displays is what keeps the result predictable |
By default two lines are duplicates only when every character matches exactly, including capital
letters and including spaces or tabs at the start and end of the line. So apple and
Apple are two different lines, and apple and apple with a
trailing space are also two different lines. Turning on Ignore case makes the comparison case
insensitive. Turning on Trim whitespace strips the spaces and tabs from both ends of every line
before the comparison happens. The two boxes can be combined.
The first one, counting from the top of the box. Later copies are dropped. When Ignore case is on and the copies are spelled differently, the surviving line keeps the spelling of the first occurrence.
A line with no characters at all, and also a line that holds nothing but whitespace such as spaces and tabs. That rule does not depend on the Trim whitespace box. A single newline at the very end of the box is treated as the end of the last line rather than as an extra empty line.
Lines are compared character by character in code order, which is the ordering the JavaScript less
than operator uses. That is not dictionary order: every capital letter sorts before every lowercase
letter, so Banana comes before apple. Turning on Ignore case compares the
lowercased text instead. The sort is stable, so lines that compare equal stay in the order they were
pasted in.
Always the same fixed order, no matter which boxes you tick: trim whitespace first, then remove empty lines, then remove duplicate lines, then sort.
No. The whole tool is a few array operations that run inside the page. There is no account, no upload, no analytics and no server side storage, and the site has no endpoint that accepts a request body at all. Nothing is written to the address bar either, so a pasted list does not end up in browser history.
This page is one of a small set of single purpose tools that run entirely in the browser, with no account and no server side storage. The set is listed below. If you write a lot of text rather than a lot of lists, the character limit checker in the same set measures a draft against the published limits of the platform you are about to paste it into.