Skip to content

Instantly share code, notes, and snippets.

@axel-angel
Created September 14, 2025 20:57
Show Gist options
  • Select an option

  • Save axel-angel/caace5a1b2dec0035deee9ba6b145afe to your computer and use it in GitHub Desktop.

Select an option

Save axel-angel/caace5a1b2dec0035deee9ba6b145afe to your computer and use it in GitHub Desktop.
structured manpage: find
{
"name": "find",
"short_desc": "search for files in a directory hierarchy",
"usage_format": "find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]",
"flags": [
{
"short": "-H",
"long": null,
"short_desc": "Do not follow symbolic links, except while processing command line arguments",
"argument": null,
"long_desc": "When find examines or prints information about files, the information used shall be taken from the properties of the symbolic link itself. The only exception is when a file specified on the command line is a symbolic link, and the link can be resolved."
},
{
"short": "-L",
"long": null,
"short_desc": "Follow symbolic links",
"argument": null,
"long_desc": "When find examines or prints information about files, the information used shall be taken from the properties of the file to which the link points, not from the link itself (unless it is a broken symbolic link or find is unable to examine the file to which the link points)."
},
{
"short": "-P",
"long": null,
"short_desc": "Never follow symbolic links (default)",
"argument": null,
"long_desc": "When find examines or prints information about files, and the file is a symbolic link, the information used shall be taken from the properties of the symbolic link itself."
},
{
"short": "-D",
"long": null,
"short_desc": "Print diagnostic information",
"argument": "debugopts",
"long_desc": "Print diagnostic information; this can be helpful to diagnose problems with why find is not doing what you want. The list of debug options should be comma separated."
},
{
"short": "-O",
"long": null,
"short_desc": "Enables query optimisation",
"argument": "level",
"long_desc": "The find program reorders tests to speed up execution while preserving the overall effect. Optimisation levels are 0-3, with 1 being default."
}
],
"formats": [
{
"name": "tests",
"short_desc": "Return true or false based on file properties",
"items": ["-name", "-type", "-size", "-mtime", "-perm", "-user", "-group", "-empty", "-executable", "-readable", "-writable"]
},
{
"name": "actions",
"short_desc": "Have side effects and return true/false based on success",
"items": ["-print", "-print0", "-exec", "-execdir", "-delete", "-ls", "-printf", "-ok", "-okdir"]
},
{
"name": "operators",
"short_desc": "Join together other items within the expression",
"items": ["!", "-not", "-a", "-and", "-o", "-or", ",", "(", ")"]
}
],
"examples": [
{
"command": "find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f",
"description": "Find and delete files named 'core' in /tmp, handling filenames with spaces safely"
},
{
"command": "find . -type f -exec file '{}' \\;",
"description": "Run 'file' command on every file in current directory and subdirectories"
},
{
"command": "find $HOME -mtime 0",
"description": "Search for files modified in the last 24 hours"
},
{
"command": "find . -perm 664",
"description": "Find files with exact permissions 664"
},
{
"command": "find . -name .snapshot -prune -o \\( \\! -name '*~' -print0 \\)",
"description": "Find files excluding .snapshot directories and files ending with ~"
}
]
}
{
"name": "actions",
"short_desc": "Have side effects and return true/false based on success",
"items": [
{
"name": "-delete",
"short_desc": "Delete files or directories",
"syntax": "-delete",
"return_value": "true if removal succeeded, false otherwise",
"notes": "Automatically turns on -depth option. Cannot be combined with -prune. Will fail to remove non-empty directories.",
"security_warning": "Don't put -delete first - it will try to delete everything below starting points"
},
{
"name": "-exec",
"short_desc": "Execute command for each file",
"syntax": "-exec command ;",
"return_value": "true if command returns 0 status",
"arguments": {
"command": "Command to execute",
"{}": "Replaced by current file name",
";": "Terminates the command (must be escaped as \\; in shell)"
},
"variants": [
{
"syntax": "-exec command {} +",
"description": "Execute command with multiple files appended, like xargs",
"return_value": "always true",
"notes": "Only one {} allowed, must appear at end before +"
}
],
"security_warning": "Inherently insecure - use -execdir instead"
},
{
"name": "-execdir",
"short_desc": "Execute command from subdirectory containing matched file",
"syntax": "-execdir command ;",
"return_value": "true if command returns 0 status",
"arguments": {
"command": "Command to execute",
"{}": "Replaced by current file name (prepended with ./)",
";": "Terminates the command"
},
"variants": [
{
"syntax": "-execdir command {} +",
"description": "Execute command with multiple files from same subdirectory",
"return_value": "always true"
}
],
"security_notes": "More secure than -exec. Ensure PATH doesn't contain '.' or empty entries."
},
{
"name": "-fls",
"short_desc": "List files in ls -dils format to file",
"syntax": "-fls file",
"return_value": "always true",
"arguments": {
"file": "Output file path (/dev/stdout and /dev/stderr handled specially)"
},
"notes": "Output file always created even if predicate never matched. Uses 1 KiB blocks unless POSIXLY_CORRECT set."
},
{
"name": "-fprint",
"short_desc": "Print full file names to file",
"syntax": "-fprint file",
"return_value": "always true",
"arguments": {
"file": "Output file path"
},
"notes": "File created/truncated when find runs. /dev/stdout and /dev/stderr handled specially."
},
{
"name": "-fprint0",
"short_desc": "Print full file names to file, null-separated",
"syntax": "-fprint0 file",
"return_value": "always true",
"arguments": {
"file": "Output file path"
},
"notes": "Like -fprint but uses null character separator instead of newline"
},
{
"name": "-fprintf",
"short_desc": "Print formatted output to file",
"syntax": "-fprintf file format",
"return_value": "always true",
"arguments": {
"file": "Output file path",
"format": "Format string with % directives and \\ escapes"
},
"notes": "Like -printf but writes to file instead of stdout"
},
{
"name": "-ls",
"short_desc": "List files in ls -dils format",
"syntax": "-ls",
"return_value": "always true",
"notes": "Block counts in 1 KiB blocks unless POSIXLY_CORRECT set (then 512-byte blocks)"
},
{
"name": "-ok",
"short_desc": "Execute command after user confirmation",
"syntax": "-ok command ;",
"return_value": "true if user agrees and command returns 0, false otherwise",
"arguments": {
"command": "Command to execute",
"{}": "Replaced by current file name",
";": "Terminates the command"
},
"notes": "Cannot be used with -files0-from option. Command's stdin redirected from /dev/null."
},
{
"name": "-okdir",
"short_desc": "Execute command from subdirectory after user confirmation",
"syntax": "-okdir command ;",
"return_value": "true if user agrees and command returns 0, false otherwise",
"notes": "Like -execdir but asks user first. Cannot be used with -files0-from option."
},
{
"name": "-print",
"short_desc": "Print full file name followed by newline",
"syntax": "-print",
"return_value": "always true",
"notes": "Default action if no other action specified. Consider -print0 for filenames with newlines."
},
{
"name": "-print0",
"short_desc": "Print full file name followed by null character",
"syntax": "-print0",
"return_value": "always true",
"notes": "Safer for filenames containing newlines or whitespace. Use with xargs -0."
},
{
"name": "-printf",
"short_desc": "Print formatted output",
"syntax": "-printf format",
"return_value": "always true",
"arguments": {
"format": "Format string with % directives and \\ escapes"
},
"format_specifiers": {
"escape_sequences": [
{"sequence": "\\a", "description": "Alarm bell"},
{"sequence": "\\b", "description": "Backspace"},
{"sequence": "\\c", "description": "Stop printing and flush output"},
{"sequence": "\\f", "description": "Form feed"},
{"sequence": "\\n", "description": "Newline"},
{"sequence": "\\r", "description": "Carriage return"},
{"sequence": "\\t", "description": "Horizontal tab"},
{"sequence": "\\v", "description": "Vertical tab"},
{"sequence": "\\0", "description": "ASCII NUL"},
{"sequence": "\\\\", "description": "Literal backslash"},
{"sequence": "\\NNN", "description": "Character with octal code NNN"}
],
"file_info": [
{"specifier": "%%", "description": "Literal percent sign"},
{"specifier": "%f", "description": "File's basename"},
{"specifier": "%h", "description": "File's dirname"},
{"specifier": "%p", "description": "File's name"},
{"specifier": "%P", "description": "File's name with starting-point removed"},
{"specifier": "%H", "description": "Starting-point under which file was found"}
],
"file_attributes": [
{"specifier": "%s", "description": "File's size in bytes"},
{"specifier": "%b", "description": "File's size in 512-byte blocks"},
{"specifier": "%k", "description": "File's size in 1 KiB blocks"},
{"specifier": "%d", "description": "File's depth in directory tree"},
{"specifier": "%i", "description": "File's inode number"},
{"specifier": "%l", "description": "Object of symbolic link (empty if not symlink)"},
{"specifier": "%n", "description": "Number of hard links"},
{"specifier": "%m", "description": "File's permission bits (octal)"},
{"specifier": "%M", "description": "File's permissions (symbolic, like ls)"},
{"specifier": "%y", "description": "File's type (like ls -l)"},
{"specifier": "%Y", "description": "File's type, following symlinks"}
],
"ownership": [
{"specifier": "%u", "description": "File's user name or numeric ID"},
{"specifier": "%U", "description": "File's numeric user ID"},
{"specifier": "%g", "description": "File's group name or numeric ID"},
{"specifier": "%G", "description": "File's numeric group ID"}
],
"timestamps": [
{"specifier": "%a", "description": "File's last access time (ctime format)"},
{"specifier": "%c", "description": "File's last status change time (ctime format)"},
{"specifier": "%t", "description": "File's last modification time (ctime format)"},
{"specifier": "%Ak", "description": "File's last access time in format k"},
{"specifier": "%Ck", "description": "File's last status change time in format k"},
{"specifier": "%Tk", "description": "File's last modification time in format k"},
{"specifier": "%Bk", "description": "File's birth time in format k (if supported)"}
],
"time_formats": [
{"format": "@", "description": "Seconds since Jan 1, 1970 GMT with fractional part"},
{"format": "H", "description": "Hour (00..23)"},
{"format": "I", "description": "Hour (01..12)"},
{"format": "M", "description": "Minute (00..59)"},
{"format": "S", "description": "Second (00.00..61.00) with fractional part"},
{"format": "T", "description": "Time, 24-hour (hh:mm:ss.xxxxxxxxxx)"},
{"format": "d", "description": "Day of month (01..31)"},
{"format": "m", "description": "Month (01..12)"},
{"format": "Y", "description": "Year (1970...)"},
{"format": "F", "description": "Date (yyyy-mm-dd)"}
],
"filesystem": [
{"specifier": "%D", "description": "Device number (decimal)"},
{"specifier": "%F", "description": "Filesystem type"},
{"specifier": "%S", "description": "File's sparseness"}
],
"selinux": [
{"specifier": "%Z", "description": "File's security context (SELinux only)"}
]
},
"notes": "Field widths and precisions supported like printf(3). Many fields printed as %s not %d."
},
{
"name": "-prune",
"short_desc": "Do not descend into directory",
"syntax": "-prune",
"return_value": "always true",
"notes": "If file is directory, don't descend into it. No effect with -depth. Cannot be combined with -delete."
},
{
"name": "-quit",
"short_desc": "Exit immediately",
"syntax": "-quit",
"return_value": "always true",
"notes": "Exit with return value 0 if no errors. Different from -prune - stops find completely. Pending -exec ... + commands are invoked before exit."
}
],
"inhibit_default_print": ["-delete", "-exec", "-execdir", "-fls", "-fprint", "-fprint0", "-fprintf", "-ls", "-ok", "-okdir", "-print0", "-printf"],
"notes": "Actions inhibit default -print unless expression contains only -prune or -quit. The -delete action implies -depth option."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment