行排序,免费
对文本行进行排序、反转、去重或随机打乱。
排序模式
关于行排序
行排序通过按选定顺序比较每一行来整理文本。字母排序适用于列表、术语表和名录。数字排序将每行视为数字并按值排序。按长度排序将短条目和长条目分组,便于排版和布局。
此工具还能去除重复行、删除空行、清理空白、反转顺序或随机打乱行。所有处理都是即时的,并在您的浏览器中完成。
常见用途
- 按字母顺序整理姓名、物品或条目列表
- 对 CSV 列值或日志条目排序
- 从文件或数据集中移除重复项
- 为抽奖或游戏随机分配打乱列表
- 按从小到大或从大到小排序数字
- 通过删除空白和空行清理数据
常见问题
数字排序如何工作?
数字排序提取每行开头的数字并按该值排序。不以数字开头的行会被放到末尾。这意味着「9 件物品」会在「10 件物品」之前(与字母排序不同,字母排序会把「10」排在「9」之前)。
「去除重复」是做什么?
此选项移除多次出现的行,仅保留首次出现。与「不区分大小写」一起使用时,仅大小写不同的行也会被视为重复。
打乱真的随机吗?
打乱使用 Fisher-Yates 算法和 Math.random()。适合日常用途,如随机化列表或抽签。它在密码学上不安全 · 如需安全等级的随机数,请使用专门工具。
什么是行排序?
行排序是按所选规则重新排序文本文件或列表的行的操作。规则可以是字典序(按其 Unicode 码点从左到右比较字符)、数字序(提取前导数字并比较值)、基于长度的(比较字符数)或随机(产生均匀随机排列的 Fisher-Yates 混洗)。每条规则回答关于您数据的不同问题。
这个工具公开了八种排序模式(A 到 Z、Z 到 A、数字升序、数字降序、最短优先、最长优先、混洗、反转)以及四个可切换选项(不区分大小写、修剪空格、删除重复项、删除空行)。这些组合涵盖了过去需要 Bash 一行命令、用 sort、uniq、awk 和 shell 管道的日常列表清理工作流。现在您粘贴行,点击一个模式和几个复选框,然后阅读结果。
所有计算都在您的浏览器中使用 JavaScript 内置的 Array.prototype.sort 进行,该函数自 2018 年起在 V8、JavaScriptCore 和 SpiderMonkey 中使用 TimSort(归并排序和插入排序的混合体,稳定且最坏情况 O(n log n))。对于不到一百万行的列表,操作完成的速度比您松开鼠标按钮所需的时间还快。
排序器内部有什么
界面堆叠三个控件:一个输入文本区域,您可以在其中粘贴行;一行八个模式按钮,会高亮显示活动选择;以及一行四个复选框,用于去重和修剪选项。下方是「排序行」操作按钮,它会产生只读输出文本区域并更新下方的行数计数器。
输入和输出上下的行数计数器让您一目了然地验证操作:如果您从 1,234 行开始,并勾选了「删除重复项」,输出计数会立即告诉您删除了多少重复项。这个快捷方式比为同一任务编写一次性 Python 或 AWK 脚本更快。
三个操作环绕在底部:「复制结果」通过 Clipboard API 将输出写入您的剪贴板,「下载 .txt」保存一个带有 LF 行结束符的 UTF-8 文本文件,「清除」清空两个文本区域。不保留任何历史记录,不保留任何设置,刷新页面会将工具返回到默认的 A-到-Z 状态。
历史和背景
Hollerith 打孔卡分拣机(1890)
Herman Hollerith 为 1890 年美国人口普查制造的打孔卡分拣机根据打孔的位置机械地将每张卡放入 12 个箱子中的一个。操作员将卡片多次通过分拣机,每个数字一次,以产生完整的数字排序。该技术称为基数排序,它在接下来的 60 年里支撑了商业计算。IBM 于 1911 年作为 Computing-Tabulating-Recording Company 成立,直接来源于 Hollerith 的机器。
John von Neumann 描述归并排序(1945)
在 1945 年关于 EDVAC 的内部报告中,John von Neumann 描述了归并排序,这是为存储程序计算机编写的第一个算法。这个想法是递归的:将列表分成两部分,对每一半进行排序,然后通过反复取较小的前置元素来合并两个已排序的一半。归并排序仍然是分而治之的教科书示例,并且是 TimSort 的基础,V8 今天用于 Array.prototype.sort 的算法。
Tony Hoare 发明快速排序(1959)
Tony Hoare,当时 25 岁,在莫斯科国立大学访学俄语,1959 年在尝试根据英语词典对俄语单词列表进行排序时设计了快速排序。该算法选择一个枢轴,围绕它对列表进行分区,并对每一侧递归。平均情况是 O(n log n),最坏情况是 O(n 平方),但由于缓存局部性,在实践中它优于归并排序。Hoare 于 1980 年获得图灵奖。
J.W.J. Williams 引入堆排序(1964)
J.W.J. Williams 于 1964 年在 Communications of the ACM 上发表了堆排序。该算法构建一个二叉堆(一棵每个父节点至少与其子节点一样大的树)并反复提取根节点。在平均和最坏情况下均保证 O(n log n),无需额外内存,但缓存不友好。堆排序是 C++ 的 std::sort(Introsort,1997)中的最坏情况回退。
ASCII 固定排序顺序(1963 到 1967)
ASCII 于 1963 年获得批准并在 1967 年修订,将代码 48 到 57 分配给数字 0 到 9,将 65 到 90 分配给大写字母 A 到 Z。0 排在 9 之前、9 排在 A 之前、A 排在 Z 之前(并且大写排在小写之前)的约定深深嵌入到自那时以来世界产生的每一个默认字典序排序中。这就是为什么「Apple」排在「apple」之前,以及为什么当您逐字符比较字符串时「10」排在「9」之前。
Unicode 排序算法(1996)
Unicode 联盟于 1996 年发布了第一个 Unicode 排序算法(UCA),编纂为 UTS #10。UCA 为每个码点提供多级权重(主要、次要、三级),以便排序可以是依赖区域设置的:在德语中,ä 可以与 a 一起排序或在 z 之后排序,具体取决于上下文;在瑞典语中,å 排在 z 之后;在西班牙语中,ñ 排在 n 之后。JavaScript 的 Intl.Collator(2014)包装了 UCA,这就是为网络上的列表排序提供动力的依据。
实用工作流
对名字列表进行字母排序
您有一个班级名册、与会者名单或从电子表格列粘贴的联系人转储。粘贴,勾选「不区分大小写」(以便「alice」和「Alice」一起排序),点击 A 到 Z。输出已准备好复制回电子表格或粘贴到电子邮件的 BCC 行。「修剪空格」可捕获来自复制粘贴伪影的多余空格。
对日志条目进行去重
您从服务器日志中导出了 5,000 条错误消息,想知道有多少不同的。粘贴,勾选「删除重复项」,点击 A 到 Z。输出计数告诉您存在多少独特错误。如果日志行有可变缩进,请与「修剪空格」结合。
为彩票或抽奖抽取名字
粘贴参赛者姓名,每行一个。点击「混洗」。输出的第一行是您的获胜者,第二行是亚军,以此类推。Fisher-Yates 实现使用 Math.random,它在统计上是均匀的,但不是密码学上安全的。对于具有法律意义的奖品抽奖,使用 CSPRNG 在服务器上运行混洗。
准备 CSV 列
当 CSV 文件的某一列中有未排序的产品 SKU 或客户 ID 时,将该列复制到文本编辑器中,粘贴到此处,按数字排序,然后粘贴回去。数字模式正确处理「9」、「10」、「100」之类的 SKU(字典序会将它们排序为 10、100、9,这很少是您想要的)。
比较两个列表的缺失项
用相同的选项对两个列表进行排序(A 到 Z、不区分大小写、修剪空格)。将它们并排粘贴到 diff 工具中。出现在一个列表中但不在另一个列表中的项变得显而易见。这比手动扫描未排序的列表更快,即使两个列表都有数千个条目也能工作。
对待办事项或工作积压进行排序
当您在纯文本编辑器中写一个待办事项列表并希望它按优先级或字母顺序排序时,粘贴到排序器中。使用「最长优先」将多步骤任务推到顶部,或使用「最短优先」先清除容易的胜利。当原始列表已经排序但方向错误时,「反转顺序」很有用。
常见陷阱
字典序 vs 数字排序
默认的 A-到-Z 排序逐字符比较字符串,所以「10」排在「9」之前,因为 ASCII 中的「1」在「9」之前。对于数字数据,请改用数字模式。对于像「file2.txt」vs「file10.txt」(自然排序)这样的混合字母数字数据,此工具不直接支持自然排序。您可以通过在排序之前用零填充数字来伪造它。
默认情况下区分大小写
默认情况下,排序区分大小写:「Apple」排在「apple」之前,因为大写 A(65)在 ASCII 中位于小写 a(97)之前。如果您想要不区分大小写的排序(不考虑大小写的字母顺序),请在点击「排序行」之前勾选「不区分大小写」复选框。
尾部空格会破坏去重
「apple」和「apple 」(带尾部空格)是不同的字符串,所以去重会保留两者。处理粘贴的数据时,始终在「删除重复项」旁边勾选「修剪空格」,否则去重计数会因看起来相同的行而膨胀。
不支持区域感知排序
此工具使用默认的 Unicode 码点排序,这对英语和许多欧洲语言是正确的,但对德语(ä、ö、ü)、瑞典语(å、ä、ö)、西班牙语(ñ)或任何有排序规则的脚本都不正确。对于区域感知的正确排序,请使用支持 Intl.Collator 的电子表格或编程语言。
稳定排序自 2019 年起得到保证
Array.prototype.sort 从 Chrome 70(2018)和 Firefox 65(2019)开始在所有主要浏览器中变得稳定。在那之前,相等的元素可能会以不可预测的方式重新排序,这破坏了任何依赖插入顺序的工作流。此工具依赖于现代稳定保证,所以相等的行会保持原始相对顺序。
Unicode 规范化影响相等性
字符 é 可以编码为单个码点(U+00E9)或 e 加组合急性重音(U+0065 U+0301)。它们看起来相同但是不同的字节序列,所以去重不会匹配它们。如果您的数据混合了两种形式,请先在编程语言中使用 NFC 进行规范化,否则期望重复项在去重过程中存活。
隐私和数据处理
您粘贴的每一行都由您浏览器中的一个小 JavaScript 函数排序。没有数据离开您的设备。我们不记录输入,不存储输出,不运行与文本内容相关的分析,也不加载可能读取文本区域的第三方 SDK。「复制结果」和「下载 .txt」按钮通过标准用户手势 API(Clipboard API 和 <a download> 技巧)与您的操作系统交互,对外部各方不可见。
页面加载后,该工具可以离线工作。您可以从网络断开连接,在隐私窗口中打开,在企业沙箱中运行,或在飞行中使用飞行模式,排序仍将完成。这使得该工具对机密客户列表、内部 SKU 以及任何不应触及第三方服务器的数据都是安全的。
什么时候不使用行排序器
对带有相关单元格的电子表格列进行排序
如果 A 列包含名字,B 列包含匹配的电子邮件地址,只复制 A 列到此处并排序会使行关系不同步。使用电子表格的内置排序,它会一起移动整行。行排序是为独立、行无关的文本设计的。
非常大的数据集(数百万行)
该工具将整个输入和输出保留在内存中,并以同步方式运行,这可能会冻结具有数百万行输入的浏览器选项卡。对于这种规模的数据集,请使用命令行排序(Unix sort、sort -u、sort -n),它通过外部归并排序处理任意大的文件。
实时流数据
如果新行每秒都在到达(例如实时日志提要或 websocket 流),此工具无法跟上。它专为静态文本的批处理而设计。对于流式排序,使用带有排序索引的数据库,或带有优先队列的编程语言。
结构化数据(JSON、带引号的 CSV)
JSON 数组、带有嵌入逗号(在带引号字段内)的 CSV 文件或 XML 元素不能作为纯文本安全排序,因为它们的分隔符跨越多行。对结构化数据排序使用 JSON 感知的排序器、CSV 解析器或 jq。
更多问题
工具使用什么排序算法?
该工具使用浏览器的内置 Array.prototype.sort,在 V8(Chrome、Edge、Node.js 自 2018 年)中是 TimSort,在 SpiderMonkey(Firefox)中是自定义归并排序。两者都是稳定的、最坏情况 O(n log n),并针对部分排序的真实世界数据进行了优化。您几乎肯定无法用自定义 JavaScript 实现来击败它们。
我可以按区域设置(德语、瑞典语、中文)进行排序吗?
在这个工具中不能。我们使用默认的 Unicode 码点排序。对于区域感知排序(瑞典语 å 在 z 之后、德语 ß 等同于 ss、西班牙语 ñ 在 n 之后),请使用具有区域设置的电子表格,或在自定义脚本中使用 JavaScript 的 Intl.Collator。该工具旨在用于英语默认工作流。
「混洗」选项到底有多随机?
混洗使用 Fisher-Yates 算法(Knuth 3.4.2),以 Math.random 作为熵源。现代浏览器中的 Math.random 使用 xorshift128+(Chrome 自 2015 年起),它在统计上是均匀的,通过了随机性测试,但不是密码学上安全的。对于奖品抽奖或任何具有法律意义的事情,请使用 crypto.getRandomValues 或服务器端 CSPRNG。
是否有最大行数限制?
没有硬性限制。该工具在中端笔记本电脑上可舒适地处理 100,000 行。在 100 万行时,预计浏览器进行排序时会暂停一到三秒。在此之上,文本区域本身成为瓶颈,工具可能会短暂挂起选项卡。对于非常大的数据集,请使用命令行工具。
为什么我的数字排序将「1.5」放在「1」和「2」之间?
数字排序使用 parseFloat 解析前导数字,它识别小数点(1.5)、科学记数法(1e3)、负数(-5)以及数字后忽略的尾随单位。如果结果不是数字,该行会移至末尾。这种行为符合大多数用户的期望,但混合整数和小数列表可能会让您感到惊讶。
排序会修改我的原始输入吗?
不会。输入文本区域保持不变。排序后的输出出现在一个单独的只读文本区域中。您可以用不同的模式或选项对同一输入进行多次排序而不会丢失原始输入。「清除」按钮是擦除输入的唯一方法,它不会要求确认,所以请有意使用它。