A little help goes a long way. Find a tool/

Text FIELD NOTES · 3 MIN READ

Per-Line Trimming: The Quiet Fix for Messy Pasted Text

Why line-by-line trimming beats a whole-text trim, and what the drop-blank-lines and collapse options decide.

The whitespace you cannot see is the whitespace that breaks things. A trailing space makes two identical-looking lines compare as different; a tab-only "blank" line refuses to behave like an empty one; a PDF paste arrives with indentation on every line. Fixing this needs to happen line by line, because a whole-text trim only touches the first and last characters of the entire block and leaves every interior line edge dirty.

What "trim every line" means

Each line is processed independently: first, optionally, every run of internal spaces and tabs is squeezed down to a single space (the collapse option); then the leading and trailing whitespace of the line is stripped. Whatever remains — including a completely empty remainder — is kept or dropped according to the second option, drop blank lines, which is on by default. Run the tool on this input and the arithmetic looks like this:

input:    "  alpha  " / "" / "  beta\tgamma  " / ""   (4 lines)
result:   "alpha" / "beta gamma"                      (2 lines)

dropped blank lines: 2     collapse: on

Notice what collapse did and did not do. The tab between beta and gamma became one space, but the line break survived untouched — collapse operates inside lines, never across them. The two blank lines were counted (droppedEmpty: 2) and removed, and the trailing blank that came from the final newline went with them, which is why 4 lines became 2.

Blank lines and the drop-blank-lines option

A "blank" line is any line that is empty after trimming — a line of six spaces or two tabs counts as blank, which is exactly what you want, since whitespace-only lines are the ones that cause comparison and parsing surprises. Turn drop blank lines off and those lines are kept as truly empty strings instead. That matters when line positions carry meaning: CSV-style data where a blank row is a record separator, or a diff-friendly file where removing lines would create phantom changes. With dropping off, the same input keeps its 4 lines and produces an empty second line rather than deleting it — the tool reports both line counts so you can tell which mode ran.

The carriage-return problem you cannot see

Line endings are three different things in the wild: \r\n on Windows, \r on classic Mac, \n everywhere else. Text pasted from a Windows editor often carries carriage returns that make each line look fine but compare as dirty. The tool splits on all three and re-joins with plain \n:

input:  "a\r\nb\rc\n  d "
result: "a\nb\nc\nd"     (line endings normalized to \n)

This normalization is a quiet bonus of running text through a line tool: mixed endings become consistent ones even though that was not the goal. Invisible characters that survive trimming — zero-width spaces and the like — are a different beast entirely, covered in Zero-Width Characters.

Where this step belongs in the pipeline

Per-line trimming is the first move in almost every cleanup, because every downstream comparison gets smarter when the padding is gone. Deduplicating apple and apple fails if you dedupe before trimming — they are different strings until the trim makes them the same one. The full story, including why the order of trim → drop empties → dedupe → sort is load-bearing, is in The Text Cleanup Pipeline. One caution: leave collapse off when internal spacing is meaningful. Code indentation, YAML structure, and aligned columns are destroyed by squeezing internal runs, while trimmed edges are always safe.

Try it yourself

Paste a messy multi-line block — indents, trailing spaces, blank lines, a tab or two — into the String Trim Lines tool and toggle both options to see each one's effect on the line counts. Feed the result to the Remove Duplicate Lines tool to watch previously "different" lines collapse into duplicates, and compare it with the Trim Whitespace tool's whole-text modes to see exactly which edges each approach can and cannot reach.

Frequently asked questions

What is the difference between this and the Trim Whitespace tool?
Trim Whitespace works on the text as one block — its trim mode touches only the first and last characters of the whole input, and its normalize mode flattens line structure. String Trim Lines works per line: every line gets its edges trimmed, and line breaks are preserved. Interior line edges — indents, trailing tabs, whitespace-only blanks — are only reachable line by line.
What counts as a blank line?
Any line that is empty after trimming, which includes lines made only of spaces or tabs — the kind that cause comparison and parsing surprises. With "drop blank lines" on (the default), those lines are removed and counted in the report; with it off, they are kept as truly empty lines, which matters when line positions carry meaning such as blank-row record separators.
Does the tool change line endings?
It normalizes them. Input split on (Windows), (classic Mac), and (Unix) is re-joined with plain , so pasted text with mixed endings comes out consistent — a quiet bonus on top of the trimming. The line structure itself is otherwise untouched.
Should I turn on the collapse option?
Only when internal spacing is noise. Collapse squeezes every run of spaces and tabs inside a line down to one space — right for pasted lists and prose — but it destroys code indentation, YAML structure, and aligned columns. Edge-trimming is always safe; internal collapsing is a judgment call.
Why should trimming happen before removing duplicates?
Because the duplicate comparison sees the strings you give it: "apple" and " apple" are different lines until a trim makes them identical, so deduplicating first reports fewer duplicates than you know are there. Trim first, then dedupe with the case and whitespace options you actually mean — the full ordering is covered in the text cleanup pipeline guide.