RPM-QUERYFORMAT(7)

πŸ’– rpm-queryformat β€” the RPM query mini-language, bestie edition πŸ’–

okay so. You know how rpm can spit out package info? This whole man page β€” rpm-queryformat(7), from the Miscellaneous Information Manual, iykyk β€” is the ✨language✨ you speak to make it say exactly what you want. It's a tiny query language, it's giving printf(3) energy, and it's honestly iconic once it clicks. Sit down, grab a strawberry πŸ“, let's go.


🌸 SYNOPSIS 🌸

✨ Query format ✨

[PLACEHOLDER|ITERATOR|EXPRESSION|TEXT ...]

πŸŽ€ Placeholder πŸŽ€

%[WIDTH]{TAG[:FORMAT]}

πŸ¦‹ Iterator πŸ¦‹

[QUERYFORMAT ...]
Note: Square brackets are literal and QUERYFORMAT must contain an array placeholder. No cap.

πŸ’… Expression πŸ’…

%|TAG?{PRESENT}:{ABSENT}|
Note: Vertical bars are literal, and PRESENT and ABSENT are query formats.

πŸ’œ DESCRIPTION πŸ’œ

RPM supports a simple query language for pulling header data out and turning it into plain text. Its syntax resembles that of printf(3), where header tags wrapped in %{ and } β€” like %{NAME}, look at her πŸ₯Ή β€” are used as placeholders. A string written in this syntax is called a query format.

Query formats are currently accepted in these places, periodt:

  1. Query operations with rpm(8), as a way to control the output (see --queryformat)
  2. rpm-scriptlets(7), to access arbitrary header data at runtime (see -q)
  3. Configuration macros in rpm-config(5) and rpmbuild-config(5), such as %_query_all_fmt or %_rpmfilename

See the EXAMPLES section for more details. πŸ‘‘


🌈 SYNTAX 🌈

A valid query format is composed of optional literal text and zero or more placeholders. A placeholder has the following syntax:

%[WIDTH]{TAG[:FORMAT]}

When RPM produces output according to a query format, it substitutes each placeholder with the TAG data from the queried package and formats the data according to the specified WIDTH and FORMAT (if given). The rest of the query format is copied to the output unchanged. No notes, it just passes through like it owns the place. πŸ’

Special characters such as \n or \t, with the exception of \0, are also supported. Curly braces, the percent sign and the backslash may be escaped with a backslash.

The individual components of a placeholder, as well as some additional language features, are described in the subsections below.

🏷️ Tags

Every RPM package contains a key-value store (the header) that represents the package's properties, such as its name, version or file list. The keys in this store are called tags, and can be used in a query format as placeholders for the values (data) they point to. The data is either a single scalar (string, integer or binary blob), or an array (argv) of multiple scalars of the same type.

To obtain a list of all tags supported by the installed version of RPM, run the following command:

rpm -v --querytags

This will print a list of available tags, along with their internal numbers and types, for example:

BASENAMES              1117 argv
BUILDHOST              1007 string
BUILDTIME              1006 int32
DESCRIPTION            1005 i18nstring
EPOCH                  1003 int32
INSTALLTIME            1008 int32
NAME                   1000 string
RELEASE                1002 string
SIZE                   1009 int32
SUMMARY                1004 i18nstring
VERSION                1001 string

Tags are case-insensitive, bestie. Each tag also has an implicit variant with the RPMTAG_ prefix, such as RPMTAG_NAME. Both variants can be used in a query format interchangeably. 🫢

See the tags documentation in SEE ALSO for more details.

🎨 Formats

Each tag is printed in a specific output FORMAT. When no format is specified, the default :string is used which displays a bare-bones representation of the data. You can specify a different format by appending its name after a colon, for example:

%{INSTALLTIME:date}

This is useful for tags that are not stored in human-readable form, such as sizes, dates or signatures. Some formats allow for performing more complex transformations of the data, such as encoding it in base64 or wrapping it in JSON syntax.

The following formats are currently available:

  • :armor β€” Wrap a public key in ASCII armor
  • :arraysize β€” Display number of elements in array tags
  • :base64 β€” Encode binary data using base64
  • :date β€” Use strftime(3) "%c" format
  • :day β€” Use strftime(3) "%a %b %d %Y" format
  • :depflags β€” Format dependency comparison operator
  • :deptype β€” Format dependency type
  • :expand β€” Perform macro expansion
  • :fflags β€” Format file flags
  • :fstate β€” Format file state
  • :fstatus β€” Format file verify status
  • :hashalgo β€” Display hash algorithm name
  • :hex β€” Format in hexadecimal
  • :octal β€” Format in octal
  • :humaniec β€” Human readable number (in IEC 80000) where K = 1024, M = 1048576, ...
  • :humansi β€” Human readable number (in SI) where K = 1000, M = 1000000, ...
  • :json β€” Wrap data in JSON
  • :perms β€” Format file permissions
  • :pgpsig β€” Display signature fingerprint and time
  • :shescape β€” Escape single quotes for use in a script
  • :string β€” Display string format (default)
  • :tagname β€” Display tag name
  • :tagnum β€” Display tag number
  • :triggertype β€” Display trigger suffix
  • :vflags β€” Format file verification flags
  • :xml β€” Wrap data in simple XML markup

Note that some formats are type specific, which means they can only be used with a specific tag type. If you attempt to use them with an incompatible type, RPM will replace them with a placeholder text. For example, the following query format will result in the output (not a number):

%{NAME:date}

Similarly, if a tag is not present in the queried package, it will be replaced with the text (none). Yeah. The tag ghosted you and RPM wrote (none) about it. πŸ’€

πŸ“ Width

You can specify the minimum WIDTH of the data when printed, by placing a number in between the % and { characters, similarly to field width used in printf(3). Optionally, prefix the number with the minus sign to left-justify the text. Aesthetic alignment, we love to see it. ✨

πŸ” Iterators

Tags pointing to arrays may be expanded to the individual elements by using iterators. An iterator is a query (sub-)format enclosed in square brackets that contains a placeholder for an array, for example:

[%{FILENAMES}\n]

RPM will loop through the enclosed array, outputting the (sub-)format each turn and substituting the placeholder with the current element. This example includes a newline character, which will result in one filename per line.

Multiple arrays may be placed into a single iterator. RPM will then iterate over all of them in lockstep, meaning that the first iteration will substitute each placeholder with its array's first element, the second iteration will use each array's second element, and so on. For example:

[%10{FILESIZES} %{FILENAMES}\n]

This is useful with parallel arrays that RPM keeps internally. These are sets of arrays where all elements at the same index correspond to each other. One can think of parallel arrays as table columns that can be arbitrarily rearranged. The above example will output a table of files and their sizes.

Sometimes, it is useful to combine an array with one or more scalars in the same iterator. This is possible since RPM internally treats all scalars as arrays of size one. However, iterators may only contain arrays of the same size, otherwise RPM will complain. 😀 To avoid that, you can "lock" an array so that only its first element is used in each iteration, by prefixing the tag with the equal sign, for example:

[%{=NAME} %{FILENAMES}\n]

This will produce an "annotated" file list where each filename is preceded by the name of the package that contains it. Gorgeous. Obsessed. πŸ‘‘

πŸ€” Expressions

Simple conditionals may be evaluated through query expressions in the form of

%|EXPR|

where EXPR is an expression.

The only type of expression currently supported is a C-like ternary operator for simple if/then/else conditions, which has the syntax

%|TAG?{PRESENT}:{ABSENT}|

where PRESENT and ABSENT are query formats that should be expanded if the queried package does and doesn't have the TAG, respectively. Thus, expressions can be nested. Nested conditionals?? It's giving inception, and I'm here for it. πŸŒ€


πŸŽ€ EXAMPLES πŸŽ€

🌟 Example 1. Query commands 🌟

  • rpm -qa --queryformat "%-30{NAME} %{SIZE:humaniec}\n" Print a table of all installed package names and their human-readable sizes.
  • rpm -q --queryformat "%{NAME} %{INSTALLTIME:date}\n" fileutils Print the fileutils package name followed by its installation date.
  • rpm -q --queryformat "[%{FILEMODES:perms} %{FILENAMES}\n]" rpm Print all filenames owned by the rpm package, one per line, with each name preceded by a file permissions string similar to the long listing format of ls(1).
  • rpm -q --queryformat "[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\n]" vlock Print all capabilities on which the vlock package depends in the form of version comparisons, one per line, with the capability name and the required version as the left and right operand, respectively.
  • rpm -qa --queryformat "%-30{NAME} %|PREINPROG?{ %{PREINPROG}}:{ no}|\n" Print a table of all installed package names in the left column and the program names used for their prein scriptlets (such as the default /bin/sh) in the right column, with the latter being no if the given package has no prein scriptlet.

πŸ’« Example 2. Command aliases πŸ’«

  • /usr/lib/rpm/rpmpopt-VERSION A popt(3) alias file used by rpm(8) itself to implement various shorthand options (such as --scripts) with the help of query formats. Replace VERSION with the version of RPM installed on your system.

🧚 Example 3. Transaction scriptlets 🧚

Print the exact file list of a package after its installation:

%post -q
for f in [%%{instfilenames} ]; do
    echo $f
done

Note that the trailing space inside the square brackets is required in order for the query format to be expanded to separate words that the for statement can loop over. Don't come for the space, the space is load-bearing bestie. 🫢

See rpm-scriptlets(7) for more information on scriptlets in general.


πŸ‘€ SEE ALSO πŸ‘€

rpm(8), rpm-common(8), rpm-config(5), rpm-scriptlets(7), rpm-spec(5), popt(3)

https://rpm.org/docs/latest/manual/tags


and that's the whole page, no crumbs left πŸ’… β€” this was RPM 6.1.0, dated 2026-08-20. go forth and format your queries, you absolute main character. πŸŒΈβœ¨πŸ¦‹

πŸ“¦ where this page comes from