Works with

Terminal OCR on Mac: capture commands and script Unpixel

Use on-screen OCR with Terminal on a Mac: copy commands from videos and screen shares safely, start captures with open unpixel://, and pipe text with pbpaste.

Title card: Terminal OCR on Mac: capture commands and script Unpixel

Terminal is where copied commands end up, and where the most damage is done when a copy is wrong. Most of the time you don’t need OCR there at all. It earns its place when the command only exists as pixels: in a tutorial video, on a colleague’s shared screen, in a screenshot pasted into a ticket. This page covers capturing those safely, and driving captures from the shell.

Quick answer

Text in your own Terminal window is already text: select it, or pipe output to pbcopy. OCR is for commands you can only see, in a video, a screen share or a screenshot. Capture them, paste at the prompt and read every character before pressing Return. To script a capture, run open "unpixel://capture", wait for the clipboard to change, then read it with pbpaste.

Your own Terminal is already text

Anything in your own Terminal window can be copied exactly, so use that first:

  • Select and copy. Drag over the output and press ⌘C. Hold ⌥ while dragging to select a rectangle, such as one column of a listing.
  • Pipe it. some-command 2>&1 | pbcopy puts all of the output, errors included, on the clipboard.

Copying text from Terminal covers ssh, tmux and saving a whole session. Reach for recognition only when there’s nothing to select.

Commands from videos and screen shares

A command in a video or in someone else’s Terminal on a call is a picture of text. To get a clean capture:

  1. Look for the source. A gist, a README or the presenter’s notes are exact. Ask for a paste in the meeting chat before you capture anything.
  2. Pause on a sharp frame. Video compression smears small monospaced text, especially just after the picture moves.
  3. Make it big. Full-screen the video or expand the shared screen. More pixels per character means fewer look-alike mistakes.
  4. Select only the command. Leave out the prompt (%, $ or user@host), line numbers and the output underneath.

A command split over several lines with \ at the ends is one command. Capture all of its lines together, and check that every backslash survived.

Read before you run

Paste the command at the prompt, but don’t press Return yet. With zsh, the default shell on macOS, a paste is inserted into the command line and waits for you. Then check:

  • Look-alikes: 0 and O; 1, l and I; rn read as m.
  • Punctuation: curly quotes instead of straight ones, a long dash where -- belongs, a missing ~ or /.
  • What it does: sudo, rm -rf, chmod -R, anything piped into sh or bash, and any URL it downloads from. Make sure you’d run it if you’d typed it yourself.

For long commands, paste into a text editor first, fix them there, and copy the corrected version. Don’t rely on a shell to hold a multi-line paste for you over ssh or in other shells.

Start a capture from the shell

Unpixel opens unpixel:// links, so the shell can start a capture with open:

open "unpixel://capture"              # crosshair, the same as ⇧⌘2
open "unpixel://capture?translate=1"  # copy a translation instead
open "unpixel://clipboard"            # read the image on the clipboard

If Unpixel isn’t running, open launches it and the capture starts once it’s ready. The command returns straight away, though, before you’ve dragged anything. To use the result in the same command line, wait for the clipboard to change. Add this function to ~/.zshrc:

# grab: drag over text on screen, get it on stdout. grab -t translates.
grab() {
  local url="unpixel://capture" before now i
  [[ $1 == -t ]] && url+="?translate=1"
  before=$(pbpaste)
  open "$url"
  for i in {1..120}; do            # wait up to 60 seconds
    sleep 0.5
    now=$(pbpaste)
    if [[ $now != "$before" ]]; then
      print -r -- "$now"
      return 0
    fi
  done
  print -u2 "grab: the clipboard didn't change"
  return 1
}

Open a new Terminal window, type grab, and drag over the text. Some uses:

Two captures appended to a text file with grab
A small shell function starts a capture, waits for it, and hands the text to the next command.
  • grab >> ~/captures.txt keeps a running log of values from a call.
  • dig +short "$(grab)" looks up a hostname you can only see on someone’s screen.
  • grab -t | wc -w translates a passage and counts its words, a quick check before it goes into a fixed-size field.

Two limits: if you press Esc, or capture exactly what was already on the clipboard, the function waits out its 60 seconds and reports that nothing changed.

Pipe the clipboard

Captured text is on the clipboard as plain text, so pbpaste hands it to any command:

pbpaste | column -t -s $'\t'        # line up a captured table
pbpaste | tr '\t' ','               # quick CSV, if no cell holds a comma
pbpaste | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort -u   # IPv4 addresses
pbpaste | tr -d ' ' | pbcopy        # strip spaces from a serial number

A captured table reaches pbpaste as tab-separated text unless you’ve changed Tables as plain text in Unpixel’s settings. macOS’s column skips empty fields, so a row with a blank cell shifts left. For sparse tables, right-click the table in the history, choose Copy as CSV and run pbpaste > table.csv.

When you’re the one presenting

If people will copy commands from your screen, make it easy for them. Press ⌘+ to make Terminal’s font bigger, use a plain high-contrast profile, and clear old output with ⌘K before a demo. Best of all, paste the commands into the meeting chat as well.

In Unpixel

Inside a capture, Unpixel treats terminal text differently from tables. Listings such as ls -l output stay plain text, one line per row, even though their columns line up. For commands, two settings in Settings → Recognition matter: turn off Language correction, which can “correct” flags and file names into dictionary words, and keep Keep line breaks on so each command stays on its own line. Every capture also lands in the local history with the app it came from, so a command you grabbed from a video an hour ago is a search away.

Frequently asked questions

Does pasting a command into Terminal run it straight away?

In zsh, the default shell on macOS, a paste is inserted into the command line and waits for you to press Return. Other shells, older setups and some remote sessions can run each pasted line as it arrives, so paste long commands into an editor first.

Can a script read the screen without me selecting anything?

Not with Unpixel. Its URL scheme starts an interactive capture, and you drag the area yourself. There is no command that reads the screen on its own.

Why did a captured table lose columns when I piped it through column?

The column tool on macOS skips empty fields, so a row with a blank cell shifts left. Copy the table as CSV from the history instead, which keeps empty cells.

Sources

  1. Keyboard shortcuts in Terminal on Mac — Apple Support support.apple.com
  2. Zsh Line Editor (bracketed-paste) — zsh documentation zsh.sourceforge.io