Line Sorter
Sort lines alphabetically, naturally (file9 before file10), by length, or shuffle — with optional dedupe, trim, reverse.
Line Sorter Tool
How to use the line sorter
Paste your lines
One item per line in the left textarea. Anything works — file names, email addresses, log entries, code identifiers.
Pick a sort mode
Natural sorts numbers like a human (file2 before file10). Alphabetical is the strict character-order sort. Length orders shortest-to-longest. Shuffle randomises.
Toggle the options
Dedupe removes duplicates (case-insensitive if that option is also on). Trim strips leading/trailing whitespace. Reverse flips the final order. Keep blanks preserves empty lines.
Copy, download, or chain
Use the copy / download buttons for the result, or click Output → Input to pipe the sorted lines back through another transform (e.g. sort, then dedupe, then shuffle).
Sorting lines — alphabetical vs natural vs length
Sorting a list of lines sounds trivial — alphabetical means A before B, right? It does, except when your list contains numbers, mixed cases, or human-meaningful patterns. file1.txt, file2.txt, file10.txt alphabetically becomes file1.txt, file10.txt, file2.txt because "1" < "2" character-wise. That's correct by the rules of lexicographic comparison and almost never what you want. Natural sort — treating runs of digits as numbers — produces the intuitive ordering and is the right default for filenames, version numbers, and most human-curated lists.
When to use each mode
Alphabetical (strict lexicographic) is right when you have no embedded numbers and care about exact character order — e.g. a list of names, words, slugs, or labels. Natural is right when your lines contain numbers that should sort numerically — file paths, version tags, sortable identifiers, episode titles. Length is right when you're spotting outliers — the longest URL in a log, the shortest acceptable password from a generated list, the most concise variant of a wording. Shuffle is right when you want randomised order — e.g. randomising a list of names for a draw, picking a non-obvious anonymisation order, generating a randomised test order.
The dedupe option is more useful than it looks
A surprising amount of real-world list work is "deduplicate this thing" — extracted email addresses, log paths, queried identifiers, URLs from a crawl. The tool's dedupe pass is exact-match (line-by-line) and respects the case-insensitive toggle, so [email protected] and [email protected] collapse to one entry when CI is on. For more sophisticated email-deduplication (Gmail dot variants, plus-tag aliases), use the dedicated Email Normalizer tool.
ASEAN-specific quirks
Localised sort orders matter when handling Asian-language content. Singaporean and Malaysian English content sorts the same as global English — straightforward. Indonesian and Filipino content is similar but watch for embedded diacritics (café should sort with cafe, which JavaScript's localeCompare() handles by default in this tool). Chinese characters sort by Unicode code-point order, which roughly tracks frequency of use — not pinyin-alphabetical, not stroke-count. If you need pinyin sort, pre-convert via the Chinese Converter first.
Why shuffle uses crypto.getRandomValues
The shuffle mode runs Fisher-Yates with window.crypto.getRandomValues() as the entropy source, so the resulting order is statistically uniform across all possible permutations — no clock-seeded predictability. For a list of 100 items, that's 100! ≈ 10^158 possible orderings. Math.random()-based shuffles can only reach a few billion of those (limited by the PRNG's internal state), which sometimes matters for cryptographic-grade randomness. For everyday list shuffling, the difference is invisible; we use the secure source anyway because it's the right default.
Composing operations with Output → Input
The Output → Input button enables piping the result back through another transform. Common chains: sort first, then dedupe to eliminate adjacent duplicates and rerun stats. Or: sort length-first, output the longest 10 manually, paste back, then alphabetise. The chaining cost is one button click and no re-paste — useful when you're building a list iteratively. Power users sometimes treat the tool as a personal data-cleaning pipeline: trim, then dedupe, then natural-sort, then output to a final destination. Each step is reversible (the input textarea keeps its previous value until you click Output → Input).
Why file10 sorts before file2, and why a fair shuffle needs a crypto random source
Plain alphabetical order compares character by character, so "file10.txt" sorts before "file2.txt" — "1" comes before "2". Natural sort reads the number as a number.
JavaScript's localeCompare(undefined, {numeric: true}) gives natural sort for free — but you have to remember the second-argument options object.
The fastest comparison sort possible is O(n log n). Heapsort, mergesort, and most quicksort variants achieve this. Counting sort beats it for integer keys.
The Fisher-Yates shuffle (1938) gives every ordering an equal chance, provided its random indices are unbiased. Common alternatives (sort(() => Math.random() - 0.5)) are biased and broken.
A list of 100 lines has 100! ≈ 9.3 × 10157 possible orderings — which is why a shuffle needs a good random source to reach them all.
Timsort — invented by Tim Peters for Python in 2002, now the standard sort in JavaScript V8 and Java — combines merge sort and insertion sort for real-world data with partial existing order.
Bubble sort is named after the way large elements "bubble up" to the end of the list. It's O(n²) and almost always the wrong choice. Used only for teaching.
Stable sort means equal elements preserve their relative input order. Array.prototype.sort() in JS has been stable since ES2019; before that, behaviour varied by engine.
Alphabetical order puts "Bukit Timah Road 10" before "Bukit Timah Road 2"; natural order puts it after — pick the mode that matches what your readers expect.
Merge sort — the pattern behind sorting data too big for memory — splits the list, sorts each half and merges them, in O(n log n) comparisons.
Frequently asked questions
file2.txt comes before file10.txt instead of after. Use it for filenames, version tags, episode titles — anything where humans would expect numeric order.Math.random() gives statistically random but predictable values; crypto.getRandomValues gives unguessable ones. For non-trivial shuffles (lottery draws, anonymisation orderings), the difference matters.localeCompare() handles diacritic-equivalent characters (café vs cafe) correctly for the alphabetical and natural modes. NFKD-style canonicalisation is not applied; if you need it, normalise upstream.Method & sources
How it computes
Alphabetical, natural (numeric-aware) and length orders using the browser's Intl collation (localeCompare with numeric and base-sensitivity options), with reverse, dedupe, trim and case options, plus a Fisher-Yates shuffle drawing unbiased indices from crypto.getRandomValues by rejection sampling.
What this tool implements
- Unicode Collation Algorithm (UTS #10): accents are a secondary difference, so café sorts beside cafe rather than after z.
- ECMA-402 defines the numeric collation option that makes file2 sort before file10.
- 100 lines have 100! ≈ 9.3 × 10¹⁵⁷ orderings; rejection sampling keeps every one equally likely.
Sources
- Unicode Consortium. Unicode Technical Standard #10: Unicode Collation Algorithm. https://www.unicode.org/reports/tr10/
- Ecma International. ECMA-402: ECMAScript Internationalization API Specification (Intl.Collator, numeric option). https://tc39.es/ecma402/
Pick up where you left off
Stored only in this browser — never sent to our servers.