The uvf command — a manual for searching huge files with the free CLI

The UwView series — search with UwView, compare with UwDiff

Open and search huge files with UwView; compare two files or two folders with UwDiff. Both run on Windows, macOS and Linux. → UwDiff user manual (CLI uvd)

uvf (free CLI)
Command manual
uvp (UwView Pro CLI)
Command manual

The uvf command manual

Covers: uvf v1.9.0 “Full Spectrum” (the CLI of the free UwView).

uvf --help lists only the essentials. This page explains the rules for writing commands, with examples. As a search tool uvf stands where ripgrep stands, so this page explains it side by side with ripgrep (the mapping is in chapter 11, performance in chapter 13).
For UwView Pro’s uvp, see the uvp command manual; for the window (GUI), see the UwView User Guide.

▶ Watch the videos: YouTube playlist “UwView|English” (how to use v1.7.3.6 “Wide Field” in 8 topics, plus an overview · Japanese · Channel @uwviewapp)


Contents


1. What uvf does

  • Searches large text files (logs, CSV, OSM XML and so on) fast
  • Searches several files in one go (wildcards and subfolders too)
  • When a wildcard is expanded, leaves out files matched by .ignore / .gitignore, using the same rules as ripgrep (4.7)
  • Searches gz, bz2, xz, lzma, zst, lz4 and br files as they decompress (no external commands)
  • Searches the text inside Word, Excel and PDF files (.docx, .docm, .xlsx, .xlsm, .pdf) as it extracts it (no index is built; 6.2)
  • Opens the results in the GUI (UwView)

Building an index (.uwvz) so that later runs are fast, reading zip and pbf, tallying and replacing are features of UwView Pro’s uvp.


2. The basic shape (just two forms)

uvf <file> <term> [options]        search and print the results
uvf -open [<file>] [<term>]        launch the GUI (open the file if given, and search the term if given)

Examples:

uvf app.log ERROR                  # print the lines in app.log that contain ERROR
uvf app.log 'connection reset'     # quote a term that contains spaces
uvf app.log ERROR -i               # ignore case
uvf -open app.log ERROR            # open it in the GUI with ERROR already searched

By default the search term is taken literally (not as a regular expression). To search with a regular expression, add -E (chapter 7).

Options can go anywhere (before or after the file and the term). Only -open must go first or last.


3. Search options

Option Meaning Example
-i ignore case uvf app.log error -i
-E treat the term as a regular expression (chapter 7) uvf app.log 'code=5\d\d' -E
-v print lines that do not match uvf app.log DEBUG -v
--json one JSON object per line (chapter 5) uvf app.log ERROR --json
-H always print the file name uvf app.log ERROR -H
-h never print the file name (-h on its own shows usage) uvf '*.log' ERROR -h
--files do not search; only show what the pattern expands to (also shows how many files were excluded) uvf '**/*.log' --files
--no-ignore do not apply .ignore / .gitignore (rules added with --ignore-file still apply; 4.7) uvf '**/*.log' ERROR --no-ignore
--no-ignore-files also drop the rules added with --ignore-file (4.7) uvf '**' ERROR --no-ignore --no-ignore-files
--ignore-file <file> add exclusion rules; may be given more than once (4.7) uvf '**' ERROR --ignore-file my.ignore
--raw take Excel cells as stored values instead of the displayed ones (6.2) uvf sales.xlsx 0.5 --raw
-open show the results in the GUI (works with several files too; chapter 8) uvf app.log ERROR -i -open

Also:

Command Meaning
uvf --help usage
uvf --help files file selection in detail
uvf --help regex regular expressions in detail
uvf --version version (e.g. uvf 1.9.0 (build 26.10.13.22))
uvf --tune [file] [--apply] measure the best thread count for this machine (chapter 9)

4. Choosing files (one, several, wildcards, exclusions)

4.1 The rule that matters most: always quote the pattern

For several files or a wildcard, put the whole thing in one pair of quotes. uvf expands it itself rather than letting the shell do it.

uvf '*.log' ERROR           # ✓
uvf *.log ERROR             # ✗ the shell expands it → error
uvf a.log b.log ERROR       # ✗ error for the same reason
uvf 'a.log b.log' ERROR     # ✓

Remember: there are only two arguments, “the files” and “the term”.

4.2 Separators

  • Separate several files with spaces or commas.
  • If there is even one comma, only commas separate. Use commas for paths that contain spaces (such as Program Files).
  • Commas and spaces inside braces { } do not separate ('app.log{,.*.gz}' is one entry; 4.5).
uvf 'a.log b.log' ERROR
uvf 'logs/*.log,err/*.log' ERROR
uvf 'C:/Program Files/app/*.log,D:/logs/*.log' ERROR     # commas for paths with spaces

4.3 Wildcard symbols

Symbol Meaning Example
* any run of characters. Does not cross the folder separator (/) uvf '*.log' ERROR
? any single character uvf 'app-0?.log' ERROR
** any number of folders (including none) uvf '**/*.log' ERROR
{a,b} a or b (braces; since v1.9.0; rules in 4.5) uvf '**/*.{txt,log}' ERROR
[ ] not supported (taken literally) uvf 'app[1].log' ERROR (a file named app[1].log)

4.4 Examples

Command Targets
uvf '*.log' ERROR .log files in this folder
uvf 'logs/*.log' ERROR .log files directly under logs
uvf '*/*.log' ERROR .log files one folder down (not the ones in this folder)
uvf '**/*.log' ERROR every .log below this folder (subfolders too)
uvf 'logs/**/*.log' ERROR every .log under logs
uvf 'logs/**' ERROR every file under logs
uvf '**/2026-09/*.log' ERROR .log files directly under any 2026-09 folder
uvf 'app.log,app.log.*.gz' ERROR plain text and gz together
uvf '**/*.{txt,log}' ERROR every .txt and .log below this folder
uvf 'app.log{,.*.gz}' ERROR app.log and app.log.*.gz (same as 'app.log,app.log.*.gz')
uvf 'logs/2026-{09,10}/*.log' ERROR .log files in logs/2026-09 and logs/2026-10
uvf '/var/log/app/*.log' ERROR absolute paths work too

4.5 Rules

  • Order: as you wrote it; within one entry, by name. Each file is searched only once.
  • Hidden files and folders (names starting with . and the like) are skipped on every OS (same as ripgrep; on Windows, .git, .gitignore and the like used to be searched, fixed in 1.7.3.2).
  • Case: Linux distinguishes case; Mac and Windows do not.
  • Wildcards never pick up .uwvz files (UwView Pro’s index).
  • An entry that matches nothing is reported by name (not silently turned into zero hits).
  • Braces {a,b} (since v1.9.0):
  • Nesting ({a,{b,c}}) and empty choices ({,.gz}) are allowed.
  • One entry expands to at most 1,000 combinations. Beyond that, uvf stops (exit code 2).
  • An unclosed brace ({a,b) or one without a comma ({}, {a}) is taken literally, as part of the name.
  • If a file with exactly the written name exists, that file is used as is (no expansion).
  • An entry that matches nothing is reported as written, braces included (nothing is reported when only some of the choices match nothing).
  • The same rules apply in the file field of the window’s Command Line dialog.
  • More than 1,000 files is reported (the search does not stop). The environment variable UVF_MANY_FILES changes the threshold.
  • A bare folder name ('logs') does not work; write 'logs/**'.
  • Symlinked folders are not followed.
  • Path separators can be / or \ (Windows).
  • Files matched by .ignore / .gitignore are left out when a wildcard is expanded (4.7). This is separate from skipping hidden files.

4.6 Checking what will be searched: --files

Before searching, you can check what a pattern expands to.

$ uvf 'logs/**/*.log' --files
1   logs/app.log
2   logs/2026-09/app-0901.log
3   logs/2026-09/app-0902.log

If exclusions (4.7) left anything out, the count comes at the end (on stderr). The set of target files is the same as rg --files (the output is numbered, so it looks different; .rgignore is not read).

4.7 Exclusions (.ignore, .gitignore)

Of the files a wildcard expands to, those matched by .ignore / .gitignore are not searched (since v1.7.2.5).
The main rules are the same as ripgrep’s; comparison runs in UwTest/uv_ignore_test.sh confirm that the target list and the search results match ripgrep. The one difference is that .rgignore is not read.
If .gitignore or the like says bin/ and obj/, those are not read even with '**'. (Being tracked by git does not exclude anything; what the rules name is excluded.)

Rule Detail
Scope only files expanded from a wildcard. A file you name is never excluded (uvf 'build/app.log' term searches it even if build is excluded)
A folder you name a folder written at the front, as in 'build/**', is not excluded. The files inside are still checked against the rules (same as passing rg term build/ to ripgrep)
Files read .ignore, .gitignore, .git/info/exclude, git’s global setting ([core] excludesFile in ~/.gitconfig, or else ~/.config/git/ignore)
Where .gitignore applies only inside a git repository (some parent folder has a .git). .ignore applies outside repositories too
Parent folders exclusion files above the starting folder apply too (.gitignore up to the repository root)
Precedence strongest first: .ignore → .gitignore → .git/info/exclude → global setting → --ignore-file. Within one kind, a deeper folder wins
Excluded folders not looked inside (so a large node_modules and the like is never read, which is fast). A file inside cannot be brought back with ! (same as git)
Case case-sensitive (same as git and ripgrep; separate from the file-selection rule in 4.5)
.rgignore not read (it is ripgrep’s own name; if you need it, put the same content in .ignore)

Syntax (same as .gitignore):

Pattern Meaning
blank lines, lines starting with # ignored (\# for a literal #)
*.log matches .log at any depth
/build only directly under the folder holding that exclusion file (anchored by the leading /)
doc/*.md with a / in the middle, the path is relative to that exclusion file’s folder
build/ matches folders only
* ? [a-z] [!a-z] wildcards (* and ? do not cross /). [ ] works in exclusion patterns (but not in file selection, 4.3)
**/tmp, out/**, a/**/b any depth
!keep.log cancels an exclusion. Later lines win
trailing spaces ignored (\ for a literal space)

Exclusion files with CRLF line endings (Windows) or a leading BOM are read too.

Options:

Option Meaning Example
--no-ignore skip exclusions from .ignore, .gitignore, .git/info/exclude and the global setting. Rules added with --ignore-file still apply (same as ripgrep 15) uvf '**' ERROR --no-ignore
--no-ignore-files also drop rules added with --ignore-file (same name as ripgrep) uvf '**' ERROR --no-ignore --no-ignore-files
--ignore-file <file> add exclusion rules; may repeat. Weakest of all, so it loses to a ! in .ignore and the like. A name-only rule (*.md and the like) matches anywhere, wherever the file sits uvf '**' ERROR --ignore-file extra.ignore
--files show what will be searched (with the count of excluded files at the end) uvf '**' --files

How you are told:

  • Nothing is added to search results (excluded files are left out silently, as in grep and ripgrep).
  • --files ends with “excluded N files, M folders (not looked inside)”. To see what was left out, compare with the list produced with --no-ignore.
  • When exclusions leave a pattern with no files at all, it says “no files match: (excluded by .gitignore etc.; –no-ignore includes them)”. It does not silently return zero hits.
  • When --ignore-file added rules, the notice also says “rules added with –ignore-file are turned off with –no-ignore-files” (because --no-ignore alone does not turn them off).

Example (a repository whose .gitignore says build/, *.tmp and !keep.tmp, and whose logs/.ignore says old/):

$ uvf '**' --files
1   app.log
2   keep.tmp
3   logs/b.log
uvf: excluded 1 file, 2 folders (not looked inside) (.gitignore etc.; --no-ignore includes them)

$ uvf 'build/**' --files          # a folder you name is not excluded
1   build/a.log

$ uvf 'x.tmp' --files             # nor is a file you name
1   x.tmp

uvf '**/*.log' ERROR --no-ignore                # search without exclusions
uvf '**' ERROR --ignore-file ~/extra.ignore      # search with extra rules

4.8 Awkward names

Name How to write it Example
One file with spaces write it as is (if the whole string is an existing file, it is taken as one file; since 1.7.2.7) uvf 'sp dir/my log.txt' ERROR
One wildcard with spaces add a trailing comma (with a comma present, spaces do not separate) uvf 'C:/Program Files/app/*.log,' ERROR
Several entries with spaces separate with commas uvf 'C:/Program Files/app/*.log,D:/logs/*.log' ERROR
A name containing a comma a comma is a separator, so replace it with ?. ? matches any character, so a-b.log or aXb.log would also match. Check with --files first uvf 'a?b.log' --files, then uvf 'a?b.log' ERROR
A name starting with - prefix ./ uvf ./-debug.log ERROR
A name with [ ] write it as is (not a wildcard) uvf 'app[1].log' ERROR
A name with { } {} and {a} (no comma) can be written as is. {a,b} with a comma expands as braces, but if a file with exactly that name exists, that file is used (4.5). Check with --files first uvf 'report{1}.log' ERROR

5. Output format

Command Format
uvf app.log ERROR (one file) line<TAB>text
uvf '*.log' ERROR (several files) file:line<TAB>text
uvf app.log ERROR -H file:line<TAB>text even for one file
uvf '*.log' ERROR -h line<TAB>text even for several files
uvf app.log ERROR --json one JSON object per line: {"n":line,"line":"text"}
uvf '*.log' ERROR --json for several files, {"file":"a.log","n":…,"line":"…"}
$ uvf app.log ERROR
128 2026-09-27 10:01:02 ERROR connection reset
512 2026-09-27 10:05:44 ERROR timeout

$ uvf '*.log' ERROR
a.log:128   2026-09-27 10:01:02 ERROR connection reset
b.log:7 2026-09-27 11:00:00 ERROR disk full
  • Line numbers start at 1.
  • With CRLF line endings (Windows), only the text is printed.
  • ripgrep prints file:line:text; uvf puts a TAB after the line number. cut -f2- extracts just the text.

6. Compressed files, Word, Excel and PDF

Compressed files are searched as they decompress. No external commands (gzip, xz and so on) are used.

Format (extension) Command uvf
.gz uvf app.log.gz ERROR searched (alone or mixed with others)
.bz2 .xz .lzma .zst .lz4 .br uvf app.log.xz ERROR searched
.docx .docm .xlsx .xlsm .pdf uvf report.docx Tokyo the text is extracted and searched (since v1.9.0; 6.2)
.doc .xls uvf old.doc Tokyo not supported (old formats; save them as .docx / .xlsx in Word / Excel)
.zip uvf logs.zip ERROR not supported (unpack it first; uvp handles zip)
.pbf (OSM) uvf japan.osm.pbf 東京 not supported (uvp converts it to XML)
.tar.gz uvf logs.tar.gz ERROR not supported (a tar bundles several files; unpack it first)
.uwvz uvf app.log.uwvz ERROR not supported (UwView Pro’s index)
anything else uvf app.log ERROR treated as text
  • The format is recognised by the extension. If a .gz file does not actually contain gzip data, you are told so.
  • Plain and compressed files can be searched together in one run: uvf 'app.log,app.log.*.gz' ERROR
  • An xz file made of several blocks (the default from xz 5.6) is decompressed with several threads.

6.1 Character encoding

The encoding is detected from the start of the file (up to 256 KB). There is no option to set it.

Order Test Encoding
1 a BOM at the start UTF-8, UTF-16LE, UTF-16BE, UTF-32LE
2 no BOM, valid UTF-8 (including pure ASCII) UTF-8
3 otherwise, compare Shift_JIS and EUC-JP; the one with fewer odd bytes wins Shift_JIS or EUC-JP
4 undecided Shift_JIS

UTF-16 / UTF-32 without a BOM, UTF-32BE and other encodings (Latin-1, GBK, ISO-2022-JP …) are not detected.

6.2 Word, Excel and PDF (since v1.9.0)

uvf extracts the text of Word, Excel and PDF files as it searches. No index is built (nothing is created next to the original). One file or a pattern such as 'docs/**/*.pdf' both work.

uvf report.docx Tokyo              # Word
uvf 'expenses/**/*.xlsx' taxi      # Excel (several files)
uvf 'docs/**/*.pdf' contract -i    # PDF
uvf sales.xlsx 0.5 --raw           # Excel, by the stored value instead of the displayed one
Format Extensions What one line looks like
Word .docx .docm one line per paragraph. A table row is one line, with the cells separated by tabs. Footnotes and comments follow at the end, with a prefix
Excel .xlsx .xlsm sheet!row<TAB>column A<TAB>column B…. Cells hold the displayed value (such as 50%); with --raw, the stored value (0.5; a formula gives its result as a number)
PDF .pdf a ## page N line for each page, followed by that page’s lines in reading order (on two-column pages, the left column first)

The line number in the output is the line number in the extracted text (e.g. 2<TAB>Sales!2<TAB>apples<TAB>50%).

  • Refused: old formats (.doc, .xls), password-protected files, PDFs with no text (images only; there is no OCR) and damaged files. uvf says why and exits with code 2. Inside a pattern for several files, such a file is named and skipped, and the rest are searched (the exit code is 2 if anything was skipped).
  • Cannot be written back in the original format (the extracted text can be saved or copied in the window).
  • Opened in the window (-open), the file shows a progress bar while its text is extracted to a temporary folder, and then that text opens.
  • The component that reads Word, Excel and PDF (PdfPig, Apache 2.0) makes the uvf command larger (about 6.7 MB → 17.4 MB).

7. Regular expressions (-E)

With -E, the search term is treated as a regular expression. UwView uses .NET regular expressions. The common syntax is the same as ripgrep (Rust), but some differences change what matches (7.2).

7.1 Common syntax

Syntax Meaning Example
. any single character uvf app.log 'E.ROR' -E
* + ? {2,5} 0 or more, 1 or more, 0 or 1, 2 to 5 times uvf app.log 'code=\d{3}' -E
[abc] [^abc] [0-9] character class uvf app.log 'code=[45][0-9][0-9]' -E
( ) a|b group, alternation uvf app.log '(ERROR|WARN) disk' -E
^ $ line start, line end uvf app.log '^2026-09-27' -E
\d \w \s \b digit, word character (Japanese too), whitespace, word boundary uvf app.log '\bERROR\b' -E
(?i) ignore case (same as -i) uvf app.log '(?i)error' -E
uvf app.log 'ERROR|WARN' -E
uvf access.log '" (4|5)\d\d ' -E
uvf app.log '^2026-09-27 1[0-2]:' -E

7.2 Differences from ripgrep

Syntax uvf (.NET) ripgrep
Default uvf app.log 'a.b' (literal “a.b”; regex needs -E) rg 'a.b' app.log (regex; literal needs -F)
Lookahead / lookbehind uvf app.log 'ERROR(?=.*disk)' -E (supported) rg -P 'ERROR(?=.*disk)' app.log (with PCRE2: -P or --engine auto)
Backreferences uvf app.log '(\w+) \1' -E (supported) rg -P '(\w+) \1' app.log (with PCRE2: -P or --engine auto)
Named groups uvf app.log '(?P<code>\d{3})' -E (uvf rewrites it as (?<code>…); the standard .NET form is (?<code>\d{3})) rg '(?P<code>\d{3})' app.log
POSIX classes uvf app.log '[A-Za-z]+' -E ([[:alpha:]] is not supported; the error suggests the equivalent range) rg '[[:alpha:]]+' app.log (matches ASCII letters only)
Digits, whitespace uvf app.log '[0-9]+' -E (\d also matches full-width digits) rg '\d+' app.log (Unicode digits)
Scripts (Han, Hiragana) uvf app.log '\p{IsCJKUnifiedIdeographs}+' -E (\p{Han} is not supported; the range differs slightly) rg '\p{Han}+' app.log

Rewrite examples (1): POSIX classes → the same range as ripgrep (the lines matched do not change):

ripgrep uvf Note
rg '[[:alpha:]]+' app.log uvf app.log '[A-Za-z]+' -E \p{L} would also match Japanese and more (wider)
rg 'id=[[:digit:]]+' app.log uvf app.log 'id=[0-9]+' -E \d would also match full-width digits (12)
rg 'a[[:space:]]b' app.log uvf app.log 'a[ \t\r\n\f\v]b' -E \s would also match full-width spaces and more

Rewrite examples (2): Unicode scripts → a close range, with different matches (.NET has no script property, so a nearby range is written with Unicode blocks; the matched characters are not identical):

ripgrep uvf (close equivalent) Difference
rg '\p{Han}+' app.log uvf app.log '[\p{IsCJKUnifiedIdeographs}\p{IsCJKUnifiedIdeographsExtensionA}\p{IsCJKCompatibilityIdeographs}々〇]+' -E \p{IsCJKUnifiedIdeographs} alone misses 々, 〇 and Extension A (㐀 etc.). Kanji in Extension B and later cannot be included with block names (.NET regular expressions match one UTF-16 unit at a time)
rg '\p{Hiragana}+' app.log uvf app.log '\p{IsHiragana}+' -E block versus script gives a slightly different range (combining voiced marks and the like)
rg '\p{Katakana}+' app.log uvf app.log '[\p{IsKatakana}ヲ-゚]+' -E \p{IsKatakana} alone misses half-width kana. The long-vowel mark ー is in the block but counted as Common in the script

To include Japanese and full-width characters, use \p{L} (letters), \d (digits) and \s (whitespace). They cover a wider range than ripgrep’s [[:alpha:]] and the like.

7.3 Rules

  • Matching is line by line (no multi-line matches).
  • A single match attempt that runs over 5 seconds is stopped. Rethink the expression.
  • A mistake in the expression is reported as “Invalid regular expression” before the search starts.
  • Matching is done on characters, regardless of the file’s encoding.

8. Working with the GUI (-open)

Form What happens
uvf -open just launches the GUI (UwView)
uvf -open app.log opens app.log in the GUI
uvf -open app.log ERROR opens it with ERROR already searched
uvf app.log ERROR -i -E -open shows a search with -i -E -v in the GUI
uvf -open '*.log' ERROR shows multi-file results in the GUI (8.1)
uvf '*.log' ERROR -i -open the same (-open at the end works too; -i -E -v apply)
uvf -open '*.log' opens without searching (shows only file number 1 and the file list)
  • -open goes first or last. It cannot be combined with --json.

8.1 Viewing multi-file results in the GUI

With uvf -open '*.log' ERROR, uvf searches first and hands the results to the GUI (the GUI does not search again).

  • Right after opening, file number 1 is shown in the main tab (the first tab).
  • The line-number column of the results window reads file number:line (e.g. 3:128). The numbers are the same as in --files.
  • Selecting a row shows the real file name on the line at the bottom of the window (selecting alone does not open the file).
  • Double-click (or Enter) shows that file in the main tab and jumps to that line (the line is centred and highlighted).
  • If the file is already in the main tab, it just jumps.
  • If the file is open in an extra tab, it switches to that tab and jumps (the same file is never opened twice).
  • If it is not open anywhere, the main tab’s content is replaced with that file (the previous file is closed).
  • A compressed file (gz, bz2 and the rest) is decompressed next to the original, then opened at the matching line (no confirmation dialog; if a decompressed copy newer than the original already exists, it is used).
  • A Word, Excel or PDF file has its text extracted to a temporary folder first, then opens (progress is shown; nothing is created next to the original).
  • If a file has changed since the search, it still opens, and the status bar says “This file has changed since the search”. If the file is gone, it says “File not found”.
  • The number of hits handed to the window is capped by the “Maximum hits kept per search” setting. Even with no limit set, it stops at 1,000,000 and the window shows “Stopped at the limit” (because the text is handed over too).

8.2 File list and tabs

The “File list” button in the main window (a bulleted-list icon; the results window has the same button) opens a table mapping numbers to real files.
Buttons are icons; the name appears when you hover (since 1.7.3; Yes/No, Open/Close, Save and Cancel stay as text).

Column Content
Number the same number as --files
File the name as you wrote it (hover for the absolute path)
Hits the number of hits in that file
Size the file’s size
Far right “Main” if it is in the main tab, “Tab” if it is open in an extra tab
  • Double-click (or Enter) a row to open it.
  • “Open in tab” at the top right switches how it opens (remembered next time).
  • Off (default): the main tab’s content is replaced with that file, shown from the start.
  • On: opens that file in an extra tab. Tabs are numbered, like 2:app-0902.log.
  • Up to 8 tabs (1 main + 7 extra). With 8 open, it does not open another and says “Up to 8 tabs” (it never closes an old tab for you). Only tabs opened from this list count.
  • A file that is already open just switches to its tab.
  • The main tab cannot be closed (it has no close button). Extra tabs close like any other tab.
  • However many tabs there are, they stay on one row and scroll sideways (the mouse wheel works too). Names longer than 27 characters end in ...; hover to see the full name.
  • The main tab is grey, so you can tell it from extra tabs (since 1.7.3.4).
  • The window title reads UwView(uvf)-Full Spectrum(v1.9.0), so you can see the version.
  • zip and pbf files only get a number (they are not searched and cannot be opened).

8.3 uvf versus uvp (multi-file GUI)

Item uvf uvp
From a result to its source line reopens the file first, then jumps (a large file takes a moment) jumps within the bundled text right away
Second search reads everything again fast, thanks to the index
GUI search box searches only the one file in the main tab (search several files again from the CLI) searches the whole bundle
Narrowing, tallying no yes
zip, pbf no yes
Word, Excel, PDF extracted while searching (no index) an index next to the file (report.docx.uwvz)

9. Thread count (–tune)

Measures on this machine how many threads to use for searching.

uvf --tune                 # measure and show the recommended value
uvf --tune big.log         # measure with a large file of your own
uvf --tune --apply         # save the measured value to the settings (used by uvf; no effect on search in the free edition's window)

The default is usually fine. It helps on machines with many CPU cores or with slow disks.


10. Exit codes

Code Meaning
0 found
1 not found
2 error (missing file, bad regular expression, bad pattern, etc.)

Word, Excel and PDF files that are refused (.doc, .xls, password-protected, PDFs with no text, damaged) also give 2 (6.2). So does a brace pattern with more than 1,000 combinations (4.5).

The same as grep and ripgrep, so it works as is in shell scripts.

if uvf app.log 'FATAL' > /dev/null; then echo "FATAL found"; fi

11. ripgrep and grep cheat sheet

The examples use the file app.log, the folder logs and the term ERROR.

What you want ripgrep uvf
Literal search rg -F ERROR app.log uvf app.log ERROR
Regex search rg 'ERROR|WARN' app.log uvf app.log 'ERROR|WARN' -E
Ignore case rg -F -i error app.log uvf app.log error -i
Non-matching lines rg -F -v DEBUG app.log uvf app.log DEBUG -v
Subfolders too rg -F ERROR logs/ uvf 'logs/**' ERROR
One extension only rg -F -g '*.log' ERROR uvf '**/*.log' ERROR
Compressed files too rg -z -F ERROR app.log.gz uvf app.log.gz ERROR (no -z needed)
Always print the file name rg -F -H ERROR app.log uvf app.log ERROR -H
Never print the file name rg -F -I ERROR logs/ uvf 'logs/**' ERROR -h
List the target files rg --files logs/ uvf 'logs/**' --files (same exclusion rules; .rgignore is not read)
Honour .ignore / .gitignore rg -F ERROR . (the default) uvf '**' ERROR (the default; 4.7)
Do not exclude rg -F --no-ignore ERROR . uvf '**' ERROR --no-ignore
Add exclusion rules rg -F --ignore-file extra.ignore ERROR . uvf '**' ERROR --ignore-file extra.ignore
Drop the added rules too rg -F --no-ignore --no-ignore-files ERROR . uvf '**' ERROR --no-ignore --no-ignore-files
JSON output rg -F --json ERROR app.log uvf app.log ERROR --json (different shape)

grep’s -h (no file names) and ripgrep’s -h (help) mean opposite things. uvf follows grep (“no file names”) and shows usage only when -h is given on its own.

What it is good at: uvf suits searching large files and compressed logs quickly while honouring exclusions, then checking the results in the GUI.
For fine control over search conditions and output (surrounding lines, counts only, matched parts only, standard input and so on), ripgrep offers more (11.1).

11.1 What ripgrep has and uvf does not

The table in chapter 3 is every option uvf has. The ripgrep features below are not in uvf; where there is a workaround, it is in the right-hand column.

ripgrep What it does In uvf
rg -F -C 3 ERROR app.log (and -A -B) surrounding lines too none (UwView Pro: uvp app.log ERROR -C 3)
rg -F -w ERROR app.log whole-word match uvf app.log '\bERROR\b' -E
rg -F -x ERROR app.log whole-line match uvf app.log '^ERROR$' -E
rg -F -c ERROR app.log count of matching lines uvf app.log ERROR | wc -l (the count is also printed at the end as “N hits”)
rg -F -l ERROR logs/ names of matching files only uvf 'logs/**' ERROR --json | jq -r .file | uniq (needs jq). If no path contains a colon, uvf 'logs/**' ERROR | cut -d: -f1 | uniq also works (a shortcut that fails with Windows paths like C:)
rg -F -q ERROR app.log just whether it exists (stop at the first) uvf app.log ERROR > /dev/null (check the exit code; it reads to the end even after a hit)
rg -F -m 5 ERROR logs/ per-file hit limit none (for the first N overall, uvf 'logs/**' ERROR | head -5)
rg -o 'code=\d+' app.log print only the matched part none (to count by value, uvp’s -uniq)
rg -e ERROR -e WARN app.log (and -f) several terms uvf app.log 'ERROR|WARN' -E (no pattern file -f)
cat app.log | rg ERROR search standard input none (write it to a file first)
rg -U 'a\nb' app.log multi-line matches none (matching is line by line)
rg --hidden ERROR include hidden files none (a hidden file can still be searched by naming it)
rg -L ERROR follow symlinked folders none
rg -t log ERROR, --max-depth, --max-filesize filter by type, depth, size type and depth through the pattern (uvf '**/*.log' ERROR, uvf '*/*.log' ERROR); no size filter
rg -E sjis ERROR app.log set the encoding none (detected automatically)
rg -r 'WARN' ERROR app.log print with replacements none (UwView Pro: uvp app.log ERROR -replace WARN)
rg -0, --column, -b NUL separators, column number, byte offset none

Also, files are given as a single string (chapter 4). Names containing spaces, commas, [ ] or { } may not work as is,
and for existing scripts that pass file names one by one, ripgrep is the better fit.


12. Common stumbling blocks

Symptom Cause and fix
“Several files were passed directly” You forgot the quotes, so the shell expanded the wildcard. Quote it: uvf '*.log' term
A path with spaces matches nothing It is being split at the spaces. Separate with commas
*/*.log misses deeper subfolders * covers one level only. To go all the way down, use '**/*.log'
[[:alpha:]] gives an error Not supported in .NET regular expressions. Rewrite it as \p{L} (7.2)
A regex does not match You forgot -E (the default is a literal search)
Cannot search a zip uvf does not handle zip. Unpack it or use uvp
A Word, Excel or PDF file is refused with exit 2 Old formats (.doc, .xls), password-protected files, PDFs with no text (images only; there is no OCR) and damaged files are refused. Save a .doc / .xls as .docx / .xlsx in Word / Excel (6.2)
Hidden files are not searched By design (4.5)
A file you expect is missing It may be excluded by .gitignore / .ignore. Check the “excluded N files” line at the end of --files, and use --no-ignore to include it (4.7)
.gitignore works in a git folder but not elsewhere By design. .gitignore applies only inside a git repository. To apply rules anywhere, put them in .ignore

13. Performance (for reference)

v1.9.0 (Full Spectrum) results (14 October 2026, Mac; Windows and Linux checked)

The latest results, measured with v1.9.0 on a Mac (14 October 2026; Apple M4, 32 GB, external USB SSD). Ratios are ripgrep’s (or the other tool’s) time ÷ uvf / uvp‘s time (total of cold + hot); under 1.5× counts as on par.

The same test suite was also run on Windows and Linux to confirm that everything works correctly (correctness tests: 66 input-type checks, 34–36 multi-file checks and 43 exclusion checks all passed, and the speed runs had zero mismatches against ripgrep). Windows and Linux speeds are shown in the two right-hand columns for reference only, since the machines and conditions differ from the Mac.

ripgrep ÷ uvf / uvp (total of cold + hot) Mac Windows (reference) Linux (reference)
One 3 GB file, overall (30–32 items) 2.56 2.24 1.50
One 10 GB file, overall (30 items) 2.51 3.17 1.96
Free uvf, seven searches (3 GB / 10 GB) 1.08 / 1.08 (on par) 1.46 / 1.92 1.32 / 1.06
uvp, seven searches (3 GB / 10 GB, incl. building the index) 3.44 / 3.55 2.48 / 2.48 1.42 / 2.06
uvp, tally and sort (3 GB and 10 GB) 4.2–4.9 2.0–3.6 1.4–3.3
uvp, Shift-JIS / EUC-JP / UTF-16 (3–6 GB, from the 2nd run) 5.4–38.8 2.2–14.1 2.0–15.3
uvp, three log examples (Linux kernel, 60,000 files) 2.35–4.56 1.26–2.48 1/2.85–1/3.21
Output check 0 mismatches 0 mismatches 0 mismatches

The first run (including building the index) is about 1/1.4–1/1.7 of ripgrep for Shift-JIS and EUC-JP (the range over three runs on a Mac). Fast-to-decompress lz4 including the first run is 1/1.4. In the reference Windows and Linux runs, uvp‘s first run, zst, lz4 and first-time bundling of many files showed losses beyond 1.5×.

Details: the v1.9.0 “Full Spectrum” article.

Unless noted, the numbers below in this chapter were measured with earlier versions.

These are examples measured on one Mac. Disk, CPU and data all change the result.
The ratio is “ripgrep’s time ÷ uvf’s time”. Above 1 means uvf is faster (🟢); below 1 (written 1/x) means ripgrep is faster (🍊). Read a gap under 1.5× as “on par” (under 1.3× for totals of seven or more items).

13.1 Test environment

Item Value
Machine Mac (Apple M4, 10 cores, 32 GB RAM), external USB SSD
Version uvf 1.7.3.6, compared with ripgrep 15.2.0
Threads 8 (the default)
Data OSM (Japan) XML. 1G = 979 MB, 3G = 2,938 MB (the 1G content joined three times), 10G = 10,255 MB, 50G = 51,255 MB. The search term is 東京 (Tokyo)
Method Each time: sync → drop caches (purge) → wait 10 s → 1st run (cold) → 2nd run (hot) straight after. Time is from command start to finish
Checks In every measurement, the results were checked against ripgrep (or a combination such as sed, sort and uniq) — zero mismatches
Raw records UwTest/mac_result/20260929-095527-cspeed (3G in 13.2, and 13.3) and UwTest/mac_result/20260929-030006-suite (1G in 13.2, 13.4 and 13.5), both 2026-09-29

13.2 Searching compressed files (cold + hot total, seconds)

ripgrep runs rg -z -n -F 東京 file (using external decompressors); uvf runs uvf file 東京. One regular measurement each.

Format 1G: size rg -z uvf Ratio 3G: size rg -z uvf Ratio
Plain (baseline, rg) 979 MB 1.34 1.24 1.08 🟢 2,938 MB 3.67 3.54 1.04 🟢
gz 106 MB 0.94 0.78 1.21 🟢 318 MB 2.66 2.07 1.29 🟢
bz2 84 MB 16.30 15.59 1.05 🟢 251 MB 47.26 45.53 1.04 🟢
xz 84 MB 1.34 1.46 1/1.09 🍊 253 MB 3.53 3.81 1/1.08 🍊
lzma 85 MB 7.04 5.74 1.23 🟢 254 MB 20.80 16.99 1.22 🟢
zst 116 MB 1.15 1.07 1.07 🟢 348 MB 3.26 3.04 1.07 🟢
lz4 178 MB 0.72 0.64 1.12 🟢 533 MB 1.87 1.70 1.10 🟢
br 97 MB 1.77 1.45 1.22 🟢 292 MB 5.05 4.13 1.22 🟢
Mixed (4 plain + gz, xz, zst, bz2) 538 MB 2.39 2.29 1.04 🟢 1,615 MB 6.63 6.47 1.02 🟢
Mixed (gz, xz, zst, bz2) 97 MB 4.37 4.17 1.05 🟢 292 MB 13.31 12.13 1.10 🟢

13.3 Cold and hot runs broken down (3G, seconds)

Format Tool 1st run (cold) 2nd run (hot)
Plain rg 3.34 0.33
Plain uvf 3.10 0.44
xz rg -z 1.79 1.74
xz uvf 1.92 1.89
gz rg -z 1.35 1.31
gz uvf 1.04 1.03

On the second run a plain file is already in memory, so neither tool reads the disk. A compressed file is decompressed again on every run, so the second run takes about as long as the first.

13.4 Searching several files at once (cold + hot total, seconds)

A pattern such as uvf 'osm17/*.osm' 東京 against ripgrep given several files (rg -z for compressed ones).

Target Lines hit ripgrep uvf Ratio
6 plain files (one of them the 51 GB japan-latest.osm) 100,424 119.37 111.03 1.08 🟢
7 gz files 122,441 44.70 37.27 1.20 🟢
13 plain + gz files 222,865 133.66 144.64 1/1.08 🍊

13.5 One large file (total of seven searches, seconds)

Seven searches — plain, -i, -E, -E anchored at line start, -E -i, -v and -E -v — each measured cold and hot, then totalled.

Data ripgrep cold uvf cold ripgrep hot uvf hot ripgrep total uvf total Ratio (total)
3G 25.51 23.43 7.74 7.84 33.25 31.27 1.06 🟢
10G 78.38 75.02 23.06 18.73 101.44 93.75 1.08 🟢
50G 425.91 383.04 404.62 371.92 830.53 754.96 1.10 🟢

13.6 Reading the numbers

  • Compressed files are on par with ripgrep in all seven formats (1/1.09–1.29×). On gz, lzma and br uvf is about 1.2× faster; only on xz is ripgrep slightly faster (about 8–9% at both 1G and 3G). Not launching external commands should give uvf an edge, but every gap is under 1.5×.
  • For plain files, uvf is slightly faster on the cold run (reading from disk), and ripgrep is slightly faster on the hot run (reading from the cache) (0.33 s vs 0.44 s at 3G).
  • Several files are on par too (1/1.08–1.20×). On the 13 mixed plain and gz files, ripgrep came out slightly faster.
  • One large file: the seven-search totals are on par at 3G, 10G and 50G (1.06–1.10×).
  • If you search the same file again and again, UwView Pro’s uvp, which builds an index to make later runs fast, is the better fit (see the “Performance” chapter of the uvp manual).

Copied title and URL