The uvp command — manual
UwView Pro v1.6.0 ships uvp, a command you can call from a terminal. It runs the same engine and reads the same .uwvz as the GUI, so whatever you were looking at on screen, you can now pull from a script.
This page lists every command, pairs each one with its rg (ripgrep) / sed / sort / uniq equivalent, and gives measured numbers.
Three things make uvp worth having.
- Past 10 GB it is several times faster than
rg— 7.65× on a 50 GB search, 7.89× on a tally, and up to 24.18× againstsed(second run; measurements from §4). The boundary is not the file size but the second question: rg re-reads the whole file for every question, uvp keeps an index - You can move from the CLI into the GUI mid-investigation — just add
-open. The same.uwvzis reused, so nothing is rebuilt (§6) - Once you are on screen, you can keep asking — click a row and it becomes the next stage. Stages after the first only look inside the previous stage, so they come back immediately
About the numbers (please read)
Every timing on this page is a second run — the.uwvzalready exists (hot). Each item was measured assync→sudo purge→ 10 s wait → cold → hot immediately after, and rg is compared on the same hot (second) run.uvpbuilds the sidecar on the first run (3 GB 1.2 s, 10 GB 13.7 s, 50 GB 66 s — roughly 1.3 s/GB). For the first-run cost and the cold figures, see I gave UwView Pro a command line and the benchmarks page.
Setup: Mac M4, 32 GB RAM, external USB SSD, ripgrep 15.2.0, BSD sed, uvp 1.6.3 (17 September 2026). Data: OpenStreetMap Japan (XML) at 3 GB / 10 GB / 50 GB.
Every result was compared line by line againstrg/sed— 78 checks, all matching, zero mismatches.
- 1. Install and put it on your PATH
- 2. Three commands to start with
- 3. The shape of a command
- 4. Stages — and how you would write them in the CLI
- 5. Options
- 6. From the CLI into the GUI — -open (the point of uvp)
- 7. Replacing text — -replace (Edit license)
- 8. .uwvz — build it once, search it even without the original
- 9. Calling it from a script
- 10. Where uvp is the wrong tool (honestly)
- 11. How this was measured, and how to reproduce it
- Related
1. Install and put it on your PATH
After installing UwView Pro, open the app menu Help → “Command line setup…”.
| OS | Where it goes |
|---|---|
| macOS | /usr/local/bin/uvp (you may be asked for your password) |
| Windows | adds a folder to your user PATH (no admin rights needed) |
| Linux | /usr/local/bin, falling back to ~/.local/bin (log in again to pick it up) |
uvp --version # uvp 1.6.3
uvp --help # every command
The free UwView ships uvf the same way (search, -i, -E, -v, -open; no index). It is about as fast as rg: a 50 GB search takes 50.7 s against rg’s 55.4 s.
2. Three commands to start with
# 1. Find (same lines as rg -n -F)
uvp huge.log 'ERROR'
# 2. Count (instead of sort | uniq -c | sort -rn | head)
uvp huge.log 'ERROR' -uniq 'code=([0-9]+)' -head 20
# 3. Replace (instead of sed 's/A/B/g'; the file itself is never modified)
uvp huge.log 'old-host' -replace 'new-host' -out fixed.log
3. The shape of a command
uvp <file> <term> [stages…] [options] investigate (flag syntax)
uvp <file> '<term> | sort … | uniq …' quoted pipe syntax (same meaning)
uvp convert <file> [-out x.uwvz] build the .uwvz
uvp cat <file> [-out …] print the text
uvp <file.uwvz> -extract [txt|gz|zip] restore the original (free)
uvp -open [<file>] launch the app
Stages run in the order you write them, exactly like a pipeline. -uniq then -sort count is not the same as -sort then -uniq.
4. Stages — and how you would write them in the CLI
4-1. Search
| What you want | CLI | uvp |
|---|---|---|
| Literal | rg -n -F 'Tokyo' F |
uvp F 'Tokyo' |
| Ignore case | rg -n -i -F tokyo F |
uvp F tokyo -i |
| Regex | rg -n 'v="(a\|b)"' F |
uvp F 'v="(a\|b)"' -E |
| Whole word | rg -n -w 'id' F |
uvp F 'id' -w |
Measured (second run, .uwvz reused)
| Hits (50 GB) | 3 GB | 10 GB | 50 GB | |
|---|---|---|---|---|
Literal 東京 |
94,979 | rg 0.33 s / uvp 1.04 s (rg wins by 3.15×) | rg 11.23 / uvp 1.80 (6.24×) | rg 56.72 / uvp 7.41 (7.65×) |
Ignore case -i (HIGHWAY) |
11,693,479 | rg 0.62 / uvp 1.23 (rg wins by 1.98×) | rg 11.98 / uvp 1.90 (6.31×) | rg 56.59 / uvp 16.02 (3.53×) |
Regex -E (k="highway[^"]*") |
11,529,957 | rg 0.53 / uvp 1.33 (rg wins by 2.51×) | rg 10.94 / uvp 1.87 (5.85×) | rg 55.50 / uvp 15.03 (3.69×) |
Anchored regex ^ *<tag k="name" |
3,337,643 | rg 0.48 / uvp 1.09 (rg wins by 2.27×) | rg 11.05 / uvp 1.95 (5.67×) | rg 55.78 / uvp 7.04 (7.92×) |
Non-matching lines -v |
48,984,614 | rg 2.10 / uvp 3.61 (rg wins by 1.72×) | rg 11.09 / uvp 1.99 (5.57×) | rg 57.78 / uvp 29.15 (1.98×) |
On a 3 GB file already in the cache, rg wins the second run in every form (uvp always pays 0.6–1.0 s of start-up and index loading). On the same 3 GB file cold, uvp is 2.2–2.9× faster on -i and -E, and on the two-run total (cold + hot) it wins by 1.3–1.7×. From 10 GB up uvp is 4.3–6.3× even hot; at 50 GB the ratio drops on -i, -E and -v, which return more than 10 million lines (uvp holds the hits). A regex costs what its hit count costs, not what its shape costs (50 GB: anchored regex 3.34 M hits 7.04 s, literal 95 K hits 7.41 s).
4-2. Narrowing (drill-down) — just add another term
# CLI: chain pipes
rg -n -F 'k="amenity"' F | rg -F 'v="parking"'
rg -n -F 'k="amenity"' F | rg -v -F 'v="parking"' # exclude
# uvp: list the terms. Later terms search inside the previous stage's ±N window
uvp F 'k="amenity"' 'v="parking"'
uvp F 'k="amenity"' 'v="parking"' -v # exclude
uvp F 'k="amenity"' -C 3 'k="name"' # 2nd term within 3 lines
Measured (two-term narrowing, second run): 3 GB rg 0.46 s / uvp 1.04 s (rg wins by 2.26×); 10 GB rg 10.94 / uvp 1.77 (6.18×); 50 GB rg 56.09 / uvp 6.41 (8.75×). Since v1.6.2 each later stage looks only at the previous stage’s results, so a stage costs 0.24 s even at 50 GB.
-C N does not mean “print N lines of context” — it means “keep only the hits that have the next term within N lines“. rg -C merely prints context, so there is no single CLI command with this meaning.
4-3. Tally
# CLI
rg -N -o 'k="amenity" v="([^"]+)"' -r '$1' F | LC_ALL=C sort | uniq -c | sort -k1,1nr | head -20
# uvp (the key is the first capture group of a regex)
uvp F 'k="amenity"' -uniq 'v="([^"]+)"' -head 20
uvp F 'k="amenity"' -uniq 'v="([^"]+)"' -sort count -head 20 # by count
uvp F 'k="amenity"' -uniq 'v="([^"]+)"' -sort value -head 20 # by value
uvp F 'ERROR' -uniq 'code=([0-9]+)' --csv # --csv / --json
Measured (top 20, second run): 3 GB rg 0.44 s / uvp 1.02 s (rg wins by 2.32×); 10 GB rg 10.98 / uvp 1.94 (5.66×); 50 GB rg 55.36 / uvp 7.02 (7.89×). By value (-sort value) at 50 GB: rg 62.59 / uvp 6.86 (9.12×).
4-4. Order (sequence)
uvp F -seq 'login,timeout,restart' # only flows where they appear in that order
grep can only ask about a set of words, so there is no CLI equivalent (you would write a state machine in awk). 3 GB 1.18 s, 10 GB 2.85 s, 50 GB 13.20 s (second run).
4-5. First and last
uvp F 'Tokyo' -head 10 # first 10
uvp F 'Tokyo' -tail 10 # last 10
A -head N written right after a search reads from the start of the file and stops as soon as it has N hits (since v1.6.2).
The output is byte-for-byte what rg … | head -N prints, and it is the same on every run.
| 東京, second run | 3 GB | 10 GB | 50 GB |
|---|---|---|---|
rg \| head -10 ⇔ -head 10 |
rg 0.06 s / uvp 0.44 s | 0.08 / 0.45 | 0.05 / 0.55 (rg wins; both sub-second) |
rg \| tail -10 ⇔ -tail 10 |
rg 0.34 / uvp 0.97 | 10.96 / 1.63 (6.72×) | 56.04 / 6.37 (8.80×) |
head goes to rg, which can stop after N hits (uvp carries its start-up and index-load cost; the gap is 0.4–0.5 s). tail has to reach the end of the file, so uvp wins; sort | head (the shape you actually write in practice) makes sort demand every line, so it lands on the same side.
A -head N written after -uniq / -sort / -seq still means “the first N rows of the transformed list” (the top 20 of a ranking, say).
Up to v1.6.1,
-headsearched the whole file and then cut the list, which took 6.7–7.0 s on 50 GB.
5. Options
-limit N — how many hits to keep (a guard for memory)
uvp F 'ERROR' -limit 1000 # stop once 1,000 hits have piled up
uvp F 'ERROR' -limit none # unlimited (0 works too; this is the default)
The default is unlimited (since v1.6.2; it used to be 1,000,000). The GUI and the CLI share the setting; -limit overrides it for one run.
Hitting the limit returns exit code 2 plus a warning. The count is shared across all shards, and
which hits you keep is not defined — whichever shards filled the budget first.
For the first N hits, use -head N, not -limit (previous section; it matches rg | head -N).
-limit is the seatbelt that keeps a huge result from eating your memory.
| 50 GB, 東京 (94,979 hits), second run | Time | Note |
|---|---|---|
-head 10 |
0.55 s | stops after the first 10 from the start of the file (rg \| head -10: 0.05 s) |
-limit 1000 |
0.68 s | stops once 1,000 piled up (which 1,000 is undefined; exit 2. rg \| head -1000: 0.09 s) |
| default (unlimited, all hits) | 7.41 s | rg 56.72 s (7.65×) |
-out <file> — where output goes
uvp F 'ERROR' -out hits.txt # text
uvp F 'ERROR' -out hits.txt.gz # .gz / .zip are compressed as they are written
uvp F 'ERROR' -out hits.txt --force # overwrite (refused by default)
Measured (second run): text, rg -n > file 50 GB 55.36 s / uvp 5.92 s (9.35×), 10 GB 22.23 / 1.80 (12.35×). Compressed, rg \| gzip > out.gz 50 GB 71.91 s / uvp -out out.txt.gz 6.17 s (11.65×).
The rest
| Option | Meaning | CLI counterpart |
|---|---|---|
--no-line-number |
omit line numbers | matches sed -n '/term/p' output |
--csv / --json |
tally output format | — |
-open |
at the front: run in the GUI / at the end: run, then also open the GUI | — |
Measured for --no-line-number (against sed, second run): 3 GB sed 9.91 s / uvp 1.05 s (9.44×); 10 GB sed 13.11 / uvp 1.61 (8.14×); 50 GB sed 145.35 / uvp 6.01 (24.18×). sed works line by line, so even 3 GB takes 10 s.
6. From the CLI into the GUI — -open (the point of uvp)
uvp lets you carry an investigation from the terminal into the window. Same engine, same .uwvz, so there is nothing to wait for on arrival.
# -open at the end … run in the CLI, print the result, and hand it to the GUI as well
uvp osm/japan-latest.osm 'k="amenity"' -uniq 'v="([^"]+)"' -head 20 -limit none -open
# -open at the front … don't run in the CLI; run it in the GUI and watch it there
uvp -open osm/japan-latest.osm 'k="amenity"' -uniq 'v="([^"]+)"' -head 20 -limit none
With -open at the end — the terminal prints the result, and the same tally appears in the app.

With -open at the front — the GUI does the work, and you carry on with the mouse.

The part that matters — it stays fast after you arrive
In the window you can keep adding questions to the same file.
- Click a row and it becomes the next stage (“Click a row to narrow down to that value in a new stage.”). Click
parkingand a new tab opens fork="amenity"andparking - Stages after the first only look inside the previous stage, so there is no wait. Changed your mind? Go back to that tab. You never rebuild a pipeline and re-read 51 GB
- Switch between Drill-down / Sequence, and hit
Tally,SortorSave CSVright there - On a 51 GB, 892-million-line file, the tally on screen took 4.45 s (see “Last: Tally 4.45 s” in the status bar)
So the way to use uvp is:
CLI in scripts and cron (several times faster than
rgpast 10 GB). Once you have a lead,-openhands it to the GUI, where you can re-narrow as many times as you like.
Faster than rg on its own, and once it is on screen you can change the question with the mouse — that round trip is what a grep / rg pipeline cannot give you.
7. Replacing text — -replace (Edit license)
# CLI
sed 's/Tokyo/TOKYO/g' F > out.txt
sed -E 's/v="(bus_stop|traffic_signals)"/v="X_\1"/g' F > out.txt
rg -N -F --passthru 'Tokyo' -r TOKYO F > out.txt
# uvp (the source file is never modified; the whole text is written out)
uvp F 'Tokyo' -replace TOKYO -out out.txt
uvp F 'v="(bus_stop|traffic_signals)"' -E -replace 'v="X_$1"' -out out.txt
With -E you can insert capture groups as $1, $2 ($$ is a literal $). The output is byte-for-byte identical to sed / rg --passthru — verified on every size.
Measured (time to write the whole file out; uvp 1.6.2, 16 September 2026 — the replace path did not change in v1.6.3, so it was not re-measured)
| 3 GB | 10 GB | 50 GB | |
|---|---|---|---|
uvp -replace |
4.57 s | 13.47 s | 69.75 s |
sed 's/A/B/g' |
14.94 s (3.27×) | 26.51 s (1.97×) | 187.74 s (2.69×) |
rg --passthru -r |
7.06 s (1.54×) | 26.89 s (2.00×) | 146.65 s (2.10×) |
uvp -E -replace '$1' |
4.17 s | 14.08 s | 69.95 s |
sed -E (backreferences) |
24.81 s (5.95×) | 78.36 s (5.57×) | 405.52 s (5.80×) |
A replacement with backreferences runs about 6× faster than sed — 6 min 45 s versus 1 min 10 s at 50 GB.
Note that a replacement counts occurrences, not lines: for Tokyo in the 3 GB file, 11,274 lines matched but 11,361 occurrences were replaced — 87 lines held more than one.
-replaceis part of the Edit license (included in the 14-day free trial). It never rewrites the file; it writes the whole text out.
8. .uwvz — build it once, search it even without the original
uvp convert huge.log # build the .uwvz (3 GB 1.2 s, 10 GB 13.7 s, 50 GB 66 s)
uvp huge.log.uwvz 'ERROR' # search it with the original deleted
uvp huge.log.uwvz -extract -out restored.log # restore the original (free)
- It is 1/9 to 1/12 of the original (3 GB → 0.25 GB, 50 GB → 5.74 GB) — about the same as gzip, but 5× faster to create
- Unlike gzip, you search it without unpacking (5.81 s at 50 GB, second run — 12.6× the 73.32 s
rgtakes to scan the original). You can also point it at a.gzdirectly (uvp f.gz 'TERM'): it builds the.uwvzon the first run and reuses it after that (50 GB: first run 120.26 s, second 6.88 s) -extractneeds no license: 3.55 s for 3 GB, byte-identical to the original (measured with v1.6.2)
More in Keep it as .uwvz instead of gzip.
9. Calling it from a script
#!/usr/bin/env bash
if uvp /var/log/app.log 'FATAL' -limit 100 -out /tmp/fatal.txt; then
mail -s "FATAL found" ops@example.com < /tmp/fatal.txt
fi
| Exit code | Meaning |
|---|---|
| 0 | found |
| 1 | not found (same as grep) |
| 2 | error, or the limit was hit and output was cut off |
- Progress and diagnostics go to stderr, data to stdout — safe to pipe
- For large results, write to a file with
-outor cap them with-limit(memory grows with the hit count)
10. Where uvp is the wrong tool (honestly)
- Around 3 GB, when the file is already in the OS cache. On the second run rg wins the plain search by 3.15×,
-iby 1.98×,-Eby 2.51× and two-term narrowing by 2.26× (the gap is 0.6–0.7 s). Cold, though — right after a reboot, a log you last opened days ago, a USB HDD — uvp is 2.2–2.9× faster on the same 3 GB, and on the two-run total (cold + hot) it wins-i,-E, narrowing and tallies by 1.3–1.7× - When you ask exactly one question. There is no point building an index: with no
.uwvzyet,rgwins the first question at every size by 1.2–1.4× (the difference is the index build) - When you only want the first N hits.
rg | headcan stop after N, so rg wins at every size (both sub-second) - In the middle of a pipeline.
uvpis built around a.uwvzyou ask many questions of. A one-shot that feeds another command is what the CLI is good at
Where it pays off is the second question against the same file. From 10 GB up it is 4.3–6.3× even hot, and 2–24× at 50 GB (-head alone goes to rg).
11. How this was measured, and how to reproduce it
- Hardware: Mac M4, 32 GB RAM, external USB SSD (an internal SSD makes everything faster)
- Data: OpenStreetMap Japan (XML), 3,032,812,644 / 10,255,315,281 / 51,254,526,392 bytes
- Compared against: ripgrep 15.2.0, BSD sed,
sort,uniq(rg run with--no-config --color never). uvf / uvp 1.6.3, 17 September 2026 - Each item:
sync→sudo purge→ 10 s wait → cold → hot immediately after. This page shows the hot (second-run,.uwvzreused) figures, with rg on the same hot run. Cold and two-run totals are on the benchmarks page - Output was diffed against
rg/sedon every check — 78 of 78 matched, zero mismatches (replace and-extractare the 16 September v1.6.2 measurements)
Numbers move with the environment. If yours come out different, please tell us — we will check and correct this page.
Related
- I gave UwView Pro a command line — same answers as ripgrep, 7× faster at 10 GB. At 3 GB it wins too, if the cache is cold (includes the first run)
- CLI commands → UwView Pro (the GUI side of the same table)
- UwView Pro User Guide (the GUI manual)
- Download (the 14-day trial key is here too)