Text Editing & Formatting

Sort Unique Lines

Remove duplicate lines and sort the remaining text.

OfficialOn-device

Download action

What Sort Unique Lines does

Trims a list, removes exact duplicate lines, and sorts the remaining entries case-insensitively with a deterministic tie-breaker.

CategoryText Editing & Formatting
Action typeJavaScript
ResultReplace or copy text
InternetNot required

Action and outcome

Sort Unique Lines example
ActionOutcome
Sort Unique LinesSelected text: Mango Apple Pear AppleApple Mango Pear

Use Sort Unique Lines

Follow these steps to remove duplicate lines and sort the remaining text with ActionClip.

  1. Select the text you want to use.
  2. Choose Sort Unique Lines from ActionClip.
  3. Review the result, then replace the selection or copy the new text.

Requirements and privacy

  • Before you start: No setup required.
  • Your selected text: Runs locally in ActionClip’s JavaScript sandbox. Selected text does not leave your Mac.

Action configuration

The definition below is included so you can inspect how the action works before downloading it.

JavaScript definition
function run(selected_text) {
  const lines = selected_text
    .split(/\r\n?|\n/)
    .map((line) => line.trim())
    .filter(Boolean);

  function naturalCompare(a, b) {
    const chunksA = a.match(/\d+|\D+/g) || [];
    const chunksB = b.match(/\d+|\D+/g) || [];
    const count = Math.max(chunksA.length, chunksB.length);

    for (let index = 0; index < count; index += 1) {
      if (chunksA[index] === undefined) return -1;
      if (chunksB[index] === undefined) return 1;
      const partA = chunksA[index];
      const partB = chunksB[index];
      const numericA = /^\d+$/.test(partA);
      const numericB = /^\d+$/.test(partB);

      if (numericA && numericB) {
        const valueA = partA.replace(/^0+(?=\d)/, "");
        const valueB = partB.replace(/^0+(?=\d)/, "");
        if (valueA.length !== valueB.length) return valueA.length - valueB.length;
        if (valueA !== valueB) return valueA < valueB ? -1 : 1;
        if (partA.length !== partB.length) return partA.length - partB.length;
      } else {
        const foldedA = partA.toLocaleLowerCase();
        const foldedB = partB.toLocaleLowerCase();
        if (foldedA !== foldedB) return foldedA < foldedB ? -1 : 1;
      }
    }

    return a < b ? -1 : a > b ? 1 : 0;
  }

  return [...new Set(lines)].sort(naturalCompare).join("\n");
}