Search & collections
The Search menu holds collections and recursive search by file name or contents. Both show their results as a sortable list with each file’s source path, and both work with the viewer and quick preview.
- Ctrl-F: search the current folder and everything below it. Every word must match:
main rsfindsmain.rs, anda | bfinds either word. A lowercase word ignores case; a word with an uppercase letter matches case exactly. You can also use globs such as*.log, quoted phrases, paths with a slash such assrc/lib, and-wordto exclude matches, plus the filtersext:rs,toml,type:file,type:dir,type:link,size:>10M,size:1M..50M,mod:<7d(changed in the last week),mod:>1yandin:src(a folder anywhere in the path). Recent searches are listed below the form, with those made in the same folder first; click one, or press Ctrl-P and Ctrl-N in the query field, to reuse it. The dialog opens with the query and the choices you last left in it, set to the folder you are in. Names match in any alphabet whatever the case of a glob, and accented letters match however the file system stores them. Matches close to the search folder appear first, while the rest of the tree is still being read. - Alt-K: collect the marked files, or the current file, into a collection in the other panel. A collection holds references, so the file’s contents are not copied.
- Alt-V: choose a saved collection from a scrollable list that shows how many entries each has and an estimate of its size. Press F7 or N to create one. Collections are kept when Borg restarts.
- Esc: hide the results and keep the cursor, scroll position, marks, filter, and grouping.
- Alt-Shift-R: show hidden results again. A scan keeps running while its results are hidden.
- Alt-D: open Folder sizes to find folders by total size or file count. Hidden files are included by default. Alt-D opens the Ctrl-F dialog set to Folder totals; change Look for to switch between the two. Ctrl-C stops a scan.
- Alt-S: calculate the sizes of the selected folder. Alt-Shift-D: open a size tree of the current folder.
- Alt-W: maximize or restore the active result pane. Results open in a normal pane by
default. The
[+](maximize),[=](restore), and[-](fold) controls in the title bar can be clicked. Folding hides the view; Alt-Shift-R brings it back with its layout and selection. - Ctrl-S: filter the results by name or source path. An empty filter shows everything.
Searching inside files
Section titled “Searching inside files”Type text in Containing in the Ctrl-F dialog to list the files below the folder that contain
it. The name pattern still applies, so *.rs with fn main in Containing finds the Rust files
that have it. The switches beside the field work as in the find bar: Alt-C matches case exactly
(otherwise a lowercase query matches any case), Alt-W matches whole words, and Alt-R reads the
text as a regular expression. You can click the switches too. Ctrl-P and Ctrl-N in the field bring
back recent queries from the find bar and earlier searches. A search for text lists files only,
so it takes no folder totals or minimum file count, and Folder sizes has no Containing
field.
Each result shows its first matching line, with the line number, in the Match column, and the
status line adds the line number to the file’s path. F3 opens the file in the viewer at that match
with the find bar open on the query, so Enter goes on to the next one, and Ctrl-Q shows it there in
the quick view with the query marked. Markdown and JSON files open as source in both, since the
search read the file as it is, and s switches to the formatted view. F4 opens the file in Borg’s
editor at that match, with the match selected and the find bar open on the query, and Alt-E does the
same in the other panel, so the results stay in view. Borg reads the files in the background, and
the context line counts the files read. Binary files (a NUL byte in the first 8 KiB) and files over
64 MiB stay unread and are counted as binary or too large. Ctrl-C stops the search, and it stops at
20,000 files like any search.
Ctrl-R in the results, or Replace in files… in the File menu, replaces the text in the marked
files, or in every file the results show when none is marked. Type what goes in its place and press
Enter; leave the field empty to remove the text. A second question names the text and the files and
starts on No. Press Y to change them. Borg keeps no copy of the old text. The search’s switches
apply, so a whole-word search replaces whole words, and with a regular expression $1 puts back the
first group. Borg writes each file the way its editor saves, so permissions and links stay. It skips
files that are not text, are larger than 32 MiB, or changed while the job ran. The job shows in
Alt-J, and the results refresh when it ends.
Scanning files with rules
Section titled “Scanning files with rules”Set Look for to Rule matches in the Ctrl-F dialog to scan the files below the folder with YARA rules: those Borg ships and your own. The name pattern, Minimum size and Leave out build output, caches and ignored files still apply. The rules decide what to look for, so the dialog drops Containing and Minimum files.
Each result shows in the Match column the worst rule the file matched, how many more it matched, and the first bytes that rule found, as quoted text or as hex. F3 opens the file in the viewer at those bytes with the find bar on them, and F4 and the quick view land there too. The context line counts the files scanned and the rules that ran. Files over 64 MiB stay unread and count as too large, and the scan stops at 20,000 files like any search. Ctrl-C stops it.
Borg’s own rules look for:
reverse_shell: an interactive shell over/dev/tcp,ncorsocatrunning a shell, or a shell spawned on a pseudo-terminal.download_and_run: a script downloaded and piped straight into a shell.decode_and_run: base64 decoded and run as a shell command or as Python code.crypto_miner: a mining pool address, or the settings of a common miner.upx_packed: an executable packed with UPX, which unpacks itself in memory.execve_shellcode: the shell path exploit code builds before it starts a shell.ssh_key_planted: a public key appended to anauthorized_keysfile.reboot_job_fetch: a cron job that runs at every boot and downloads, decodes or runs something from a temporary folder.password_prompt: an AppleScript dialog that asks for a password with the answer hidden, as macOS stealers do.launch_agent_from_temp: a macOS launch agent or daemon that starts a program from a temporary or shared folder.preload_write: a write to/etc/ld.so.preload, which loads a library into every program on Linux.history_wiping: shell history turned off, or system logs emptied.agent_unattended: an AI coding agent started with its approvals turned off, as the Nx supply-chain attack did to search machines for secrets.hidden_prompt: a run of invisible Unicode tag characters, which can hide instructions for AI models in prompts, rule files and web pages.pickle_runs_code: a pickle, the format Python and PyTorch save models in, that runs a command when it is loaded.
Put your own rules in the rules folder beside config.toml: ~/.config/borg-commander/rules,
or the same folder under $XDG_CONFIG_HOME or $BORG_CONFIG_DIR. Borg reads every .yar and
.yara file there and in the folders below, each in a namespace of its own, so two files can
use the same rule names. Each file compiles by itself. A file with an error is left out whole,
the status line names it with the compiler’s message, the context line counts the files left
out, and the other files still run. Since every file loads on its own, a file that uses include
is left out too, and the files it includes run by themselves.
Rules can import the hash, math, string, time, elf, macho, pe, dotnet and dex
modules; a file that imports magic, cuckoo or console is left out. The variables filename,
filepath and extension hold the scanned file’s name, path and extension, as rule sets written
for THOR and LOKI expect, and filetype and owner are empty. A rule’s severity meta sets how
much a match matters: alert, critical or high make an alert, warning, medium or
suspicious a warning, and notice, low or info a notice. Without it, a score of 80 or
more makes an alert, 60 or more a warning, and less a notice. A rule with neither counts as a
warning. Its description and false_positives show with each match.
Borg ships no public rule sets, because their licenses differ. Download the ones you trust into the rules folder, and check each license before you use it at work:
- YARA Forge packages tested rules from many public sources; each rule keeps its source’s license.
- signature-base is free for non-commercial use (CC BY-NC 4.0).
- Elastic’s protection artifacts come under the Elastic License 2.0.
- ReversingLabs’ rules come under the MIT license.
Rules match patterns of bytes and know nothing of intent. Installers, security tools and their test data match too, and a file that no rule matches can still be malicious. Treat matches as leads. Scanning memory with rules says what a scan cannot see.
Finding packed executables
Section titled “Finding packed executables”Set Look for to Packed executables in the Ctrl-F dialog to list the programs below the folder whose code is as dense as compressed or encrypted bytes. Packers and protectors leave code like that, and so does malware that hides its code until it runs. Borg reads the parts of each ELF, Mach-O and PE file that the loader maps executable, every slice of a universal Mach-O binary included, and measures the entropy of up to 1,024 blocks of 4 KiB spread evenly over them. A program is listed when at least 70% of those blocks reach 7.2 bits per byte. Code compiled the usual way stays well below that. The name pattern, Minimum size and Leave out build output, caches and ignored files still apply, and the dialog drops Containing and Minimum files.
The Match column gives the share of high blocks and the highest entropy found, such as “97% high · max 8”. F3 opens the program in the viewer’s hex rows at the first high block, with the entropy strip described under Viewer and quick view beside them. The context line counts the programs read and the other files, which hold no code Borg knows how to find. Ctrl-C stops the search, and it stops at 20,000 files like any search. A packed program shows its real code only while it runs, and Entropy scan of every process looks at programs that way.
Working with results
Section titled “Working with results”Click a column heading to sort by it, and click again to reverse the order. The Left and Right menus also offer sorting, and the Search menu adds sorting by source folder and grouping by folder or file type. Enter on a group heading folds the group; Insert marks the matching files in it. Marks are kept when you sort or filter, and the footer also counts marked files that the filter hides.
F3 and Ctrl-Q open the original file, and after a search for text they open it at its first match. The quick view follows the cursor through the results and shows each file at its match, with the query marked as the find bar marks it. Alt-E opens the file in Borg’s editor in the other panel, so the results stay in view. Esc or F10 closes that editor and gives the focus back to the results, and the quick view comes back if it showed before. F5 copies to a real folder; if the other panel is a collection, F5 adds references to it instead. F6 needs a real folder as its destination. In a collection, F8 removes references and leaves the files alone; in search results, F8 asks to delete the original files. Shift-F8 deletes the original files from a collection too, after you confirm. When both a folder and files inside it are marked, the job handles the folder once. Reveal original or Alt-O opens the file’s folder in the other panel, with the cursor on the file. Left or Esc hides the results, and Alt-Shift-R brings them back where you left them. Tab switches between panels even when the shell has an unfinished command. The shell always stays in a real folder. F10 always asks before quitting.
Git and archive actions only work in real folder panels for now. To use them on a collected file, open its folder with Reveal original first.
Search limits
Section titled “Search limits”Search reads file names and metadata in a background worker that you can cancel, and stops at 20,000 matches. The context line shows whether the search has finished, any errors and skipped entries, and whether it hit that limit. Hidden folders are searched only when Show hidden files is on. Search stays on the file system where it started and does not follow symlinks to folders. The search window can limit results to files or to folders and set a minimum size.
Folder totals and the size tree
Section titled “Folder totals and the size tree”Choose Folder totals to measure every file below each folder before filtering by name, size,
or minimum file count. Borg keeps the 20,000 largest matching folders and sorts them by size;
click Files to rank them by file count instead. Use a pattern such as node_modules or
*cache*, or * to see every folder below the starting folder.
Totals add up file contents. Deleting a folder may free a different amount of disk space. Nested folders are counted in their parents’ totals as well. Symlinks are never followed, scans stay on the file system where they started, and a folder that contains itself (through a bind mount or a hard-linked folder) is counted only once. When a total is incomplete because of such a boundary, or because a subfolder could not be read or was left out, it is shown with ≥. Folder scans read metadata only, never file contents. Results appear once the measurement is done, and you can cancel the scan at any time.
Folder size tree shows the total for the starting folder and its subfolders in the current panel. Right expands a branch, or enters it if it is already expanded; Left folds a branch or selects its parent. Enter opens the folder itself. Click a branch arrow to fold or expand it, or a column heading to sort folders on the same level by name, size, or file count. Esc hides the tree, and Alt-Shift-R brings back its branches, marks, and cursor. File operations work on the real paths, and if you mark both a folder and a subfolder, a copy or delete job gets only the folder.
What searches leave out
Section titled “What searches leave out”While Leave out build output, caches and ignored files is checked, name searches skip
generated folders: node_modules, .git, Python caches and virtual environments, folders such
as target and dist that sit next to a build file (Cargo.toml, package.json), and any
folder tagged with a CACHEDIR.TAG file. They also skip files excluded by .gitignore,
.ignore, .rgignore, or .borgignore, and the globs in [search] exclude.
To change what is left out, press F4 in the search dialog or click F4 Edit. You can switch
generated folders and ignore files on or off, and add (Ins), edit (Enter), or remove (Del)
patterns. Changes are saved to the configuration file. A left-out folder still appears if its
own name matches, and the context line counts how many folders were left out. Add excluded:yes
to a query to search everything once, or hidden:yes to include hidden files. Size scans always
read everything.
On macOS, searches and size scans that start above ~/Library/Containers and
~/Library/Group Containers skip them: reading there makes macOS hold the read until someone
answers whether to allow access to another app’s data. A search started inside one of these
folders does read it.
Search history stays on this computer and only you can read it. Set
history = false under [search] to stop keeping it.
Instant search with an index
Section titled “Instant search with an index”Search → Index this folder for instant search keeps an index of every name below the active
folder, so Ctrl-F there, or in any folder below it, answers at once. The context line says when
the index was built. Borg rebuilds indexes in the background after it starts and whenever an
index is more than 15 minutes old, and the old index keeps answering until the new one is ready.
A search that leaves nothing out, or uses different exclusions, reads the folders instead, and so
does a search for text, because the index holds only names. Choose
the menu item again to stop indexing and delete the index. Indexes are kept in the cache folder
next to the size scans, and [index] in the configuration lists the indexed folders.
Counting sizes in the background
Section titled “Counting sizes in the background”To measure sizes while keeping ordinary file panels open, press Alt-I or choose
Search → Count sizes in background. Borg scans every folder below the current one, including
hidden files, and fills in each folder’s total as it finishes. You can keep browsing or use the
console while it runs. Folders still being measured show a growing total marked ≥, and totals
stay when you leave a folder and come back. The panel footer shows progress; press Alt-I
again, or click the footer, to stop the scan and keep the totals measured so far. Starting a
copy, move, or delete job stops a size scan in progress. Finished scans share their cache with
the size tree and Folder totals.
Saved size scans
Section titled “Saved size scans”Finished scans are saved on this computer. Folder totals and the size tree both reuse a saved
scan of the same folder with the same hidden-file setting. When you reopen a folder that was
measured before, its saved sizes appear at once, marked ~, with the date of the measurement
above the tree. Ctrl-R scans again in either size view, and Ctrl-C cancels. The previous
tree stays visible while it refreshes, and stays if the new scan is cancelled or fails. Ordinary
folder listings also show saved totals where they exist. Changes made outside Borg can make them
out of date, and browsing never starts a recursive scan by itself. Copy, move, and delete jobs in
Borg discard saved scans that cover the paths they changed.
The local SQLite cache keeps every measured folder for up to 16 starting folders. Trees load a
branch’s subfolders when you expand it. A branch shows up to 20,000 folders, and Folder totals
keeps the 20,000 largest matches; these display limits do not stop the scan or change the
totals. A “Files in this folder” row accounts for the bytes stored directly in an expanded
folder. Errors and skipped subfolders mark totals as incomplete. The cache lives in
~/.cache/borg-commander, or under XDG_CACHE_HOME if it is set; BORG_CACHE_DIR overrides
the location. The cache only holds measurements that can be recreated, and is separate from
collections. A hard-linked file counts once for every path it has. All sizes measure file contents, so the
space a file takes on disk can be larger or smaller.
This guide follows the main branch · Borg 0.11.0 · 1f6bce6
The latest release may not have everything described here. Release notes