PACSIFT(1)

πŸ“¦ version 0.15.0, in arch rolling

πŸ’… PACSIFT(1) β€” the pacsift page, but make it make sense

okay so bestie, welcome to pacsift from the pacutils fam β€” this is PACSIFT(1), and it's the tool that queries and filters packages. literally the group chat of package data: you ask, it filters, it delivers. πŸŽ€


✨ SYNOPSIS ✨

pacsift [options] (<field> <term>)...
pacsift (--help|--version)

that's the whole shape of it. options, then field/term pairs, or just ask for --help / --version and dip. πŸ¦‹


🌸 DESCRIPTION 🌸

so here's the vibe: by default you get the intersection of matched packages β€” like, only the ones that hit on everything. but if you give the same field multiple times, you get the union of matches for that field instead. so --description pacman --description alpm is "either", and piping two calls together is "both". iykyk. πŸ’…

oh, and important: if stdin is not connected to a terminal, the packages to filter get read from stdin. main character behavior fr fr.

you can combine it with pacinfo to show brief package info, kinda like pacman -Qs and pacman -Ss:

pacsift --name pacman | pacinfo --short

iconic. ate. no cap. πŸ”₯


πŸ‘‘ OPTIONS πŸ‘‘

  • --config=path β€” set an alternate configuration file path.
  • --dbext=extension β€” set an alternate sync database extension.
  • --dbpath=path β€” set an alternate database path.
  • --root=path β€” set an alternate installation root.
  • --sysroot=path β€” set an alternate system root. go read pacutils-sysroot(7) for the lore.
  • --null[=sep] β€” set an alternate separator for values parsed from stdin. the default is a newline "\n". if you use --null without specifying sep, "NUL" gets used instead. 🫢
  • --exists β€” exit with a non-zero value if no matches are found.
  • --not-exists β€” exit with a non-zero value if matches are found. (yes, it's the opposite, that's the whole point πŸ’€)
  • --invert β€” return packages that DO NOT match the provided search terms. chaotic but valid.
  • --any β€” return the union of matched packages rather than the intersection.
  • --exact β€” match values exactly. no fuzzy vibes.
  • --regex β€” treat string values as extended case-insensitive regular expressions.
  • --help β€” display usage information and exit.
  • --version β€” display version information and exit.

🧚 Filters

filters limit the initial set of packages to be searched. heads up bestie: they may not be used if packages are provided on stdin, and they are not affected by --invert or --any. periodt. ⭐

  • --local β€” search locally installed packages. similar to:
pacsift --repo=local | pacsift ...
  • --sync β€” search packages in sync databases. similar to:
pacsift --invert --repo=local | pacsift ...
  • --cache (EXPERIMENTAL) β€” search packages in cache directories. it's giving experimental, so, y'know. πŸ™ˆ

πŸ“ String Fields

by default, string fields use a case-insensitive substring search. if --exact is used, string fields must match val exactly. if "--regex" is used, val becomes an extended case-insensitive regular expression. slay.

  • --repo=val
  • --name=val
  • --base=val
  • --description=val
  • --packager=val
  • --group=val
  • --owns-file=path β€” file paths must match the package database; no attempt is made to resolve the provided path. note: when used with --exact, the installation root will be removed from path if present, otherwise path is used exactly as provided. you can pair it with realpath or which to more easily search for the owner of installed files:
pacsift --local --exact --owns-file="$(which pacsift)"
  • --license=val
  • --url=val

πŸ’œ Dependency Fields

dependencies can be specified in the format "<pkgname>[<cmp><version]". "cmp" may be any of: "=", "<", "<=", ">", ">=". if "version" is provided, the package dependency must be an exact match to the search term. if "version" is omitted, only "pkgname" gets compared β€” unless --exact is used. and if "--exact" is used and "version" isn't provided, only dependencies with no version specified will be matched. got it? got it. 🫑

ngl, dependency fields are not affected by --regex.

  • --provides
  • --conflicts
  • --replaces
  • --depends
  • --optdepends

🌈 Size Fields

size fields may be prefixed with any of these comparisons: "=", "!=", "<", "<=", ">", ">=". if no comparison is provided, "=" is used. the size may be followed by an abbreviated unit β€” and units are case-sensitive, so don't get cute with it. ✨

  • --size
  • --installed-size
  • --download-size

πŸ¦‹ Date Fields

date fields may be prefixed with any of these comparisons: "=", "!=", "<", "<=", ">", ">=". if no comparison is provided, "=" is used. dates may be provided as seconds since the epoch, or as any of these "strptime" formats: "%Y-%m-%d", "%Y-%m-%d %H:%M", "%Y-%m-%d %H:%M:%S". πŸ•°οΈ

  • --install-date
  • --build-date

πŸ’– Other

  • --satisfies=dependency β€” search for packages that satisfy dependency.

πŸ”₯ EXAMPLES πŸ”₯

find broken packages:

pacsift --packager allan

find large installed packages:

pacsift --local --size '>1.5GB'

find packages with either "pacman" or "alpm" in their description:

pacsift --description pacman --description alpm

find packages with both "pacman" and "alpm" in their description:

pacsift --description pacman | pacsift --description alpm

check if a package is installed:

pacsift --local --exists --satisfies pacman && echo "pacman is installed"

see how it all comes together? that's the way that it works. πŸ‘‘


πŸ’€ CAVEATS πŸ’€

okay so real talk: pacsift decides whether to read packages from stdin based on a naive check using isatty(3). so if pacsift is called in an environment β€” like a shell function or script being used in a pipe β€” where stdin is not connected to a terminal but does not contain packages to filter, you should call pacsift with stdin closed. for POSIX-compatible shells, that's done with "<&-".

like, don't be weird about it, just close stdin. πŸ™

and that's the page, bestie 🫢 β€” this whole thing is from pacutils, version dated 2025-12-04, and honestly? she ate. go filter some packages. πŸ’…βœ¨

πŸ“¦ where this page comes from