Guide
How to find invisible characters in a text file on a Mac
A line that looks right and does not compile, a key that looks identical and does not match, a CSV column that will not sort: very often the cause is a character you cannot see. Here is how to see them on a Mac, and how to take out only the ones that should not be there.
The usual suspects
- Non-breaking space (U+00A0) — what a word processor or a web page leaves in pasted text. Looks like a space, is not one.
- Zero-width space (U+200B) and its relatives — nothing at all on screen, and a different string to every program.
- Byte order mark (U+FEFF) — at the start of a file it is a mark; in the middle it
is a stray, and in a
.htaccessit stops the server. - Bidirectional controls — they reorder what a reader sees without changing what a compiler reads. That is the "Trojan Source" attack, not untidiness.
- Control characters — a NUL, a BEL, a Ctrl-Z end-of-file marker from DOS.
- Soft hyphens and odd-width spaces from typesetting.
In Terminal
cat -vet file.txt makes control characters and line endings visible, and
shows other non-ASCII bytes as M- sequences you have to decode by hand.
grep on a Mac has no -P, so searching for a specific invisible
character means typing it, which is the problem you started with.
In Volt
View ▸ Show and Hide ▸ Show Invisible Characters marks spaces with a dot, tabs with an arrow across their own width, and the end of a real line with ¬. The characters worth worrying about get marks of their own in the colour of something wrong: a space that is not a space, a zero-width character, a soft hyphen.
Control characters are always shown, whatever the setting, each drawn as a picture of its own name — ␀, ␇, ␡ — with its number over it if you ask.
Character Inspector (⌥⌘I) says exactly what the character under the caret is: its code point, its name, and its bytes in this file's character set.
Edit ▸ Text ▸ Clean Up Document… (⌥⇧⌘K) lists what is in the file that is not in the text, with a checkbox for each kind, and takes out every ticked one as a single change one Undo takes back. Bidirectional controls are reported as errors. And what it refuses to remove is the point: a tab is text, a form feed is a page mark, and the zero-width joiners inside 👨👩👧 are what make it one emoji rather than three people.
On every save, if you want. Settings ▸ Editor can take the invisible half of that out every time a file is saved.
Across a project. Project Report… runs the same scan over every file and filters to Something wrong.
Questions
How do I show hidden characters in a text file on a Mac?
In Terminal, cat -vet shows control characters and line endings. In Volt, View ▸ Show and Hide ▸ Show Invisible Characters marks spaces, tabs and line ends, and gives the suspicious ones marks of their own.
How do I find a zero-width space?
Show Invisible Characters marks it, Character Inspector (⌥⌘I) names it, and Clean Up Document… removes every one at once if you tick it.
What is the Trojan Source attack?
Bidirectional control characters that make code display in a different order from the order a compiler reads it. Volt reports them as errors rather than as untidiness.
Will cleaning up break emoji?
No. The zero-width joiners inside an emoji sequence are kept, because they are what make it one emoji.
Can it clean files automatically?
Yes: Settings ▸ Editor can remove zero-width characters, bidirectional controls, soft hyphens, odd spaces and control characters on every save.
Find what is hiding in your file
Volt is in free beta. Download it now — no account, no sign-up — and try it on the file you have in mind. Each build runs for seven days, and every update gives another seven.
macOS 13 or later, Apple silicon. About 8 MB, signed and notarised. Everything it does · what changed in this build.
Related
- Converting a file to UTF-8 — and the byte order mark.
- Converting line endings — the other invisible difference.
- The hex editor — for when you want the bytes themselves.
- Everything Volt does — the complete list.