4

I'd like to search multiple packages at one using a regexp connecting pattern with logical or |.

Assuming the two files /usr/lib/apache2/modules/httpd.exp and /usr/lib/apt/apt.systemd.daily exist:

$ sudo dpkg -S /usr/lib/apache2/modules/httpd.exp
apache2-bin: /usr/lib/apache2/modules/httpd.exp
$ sudo dpkg -S /usr/lib/apt/apt.systemd.daily
apt: /usr/lib/apt/apt.systemd.daily

why does apt-file search --regexp '/usr/lib/apache2/modules/httpd.exp|/usr/lib/apt/apt.systemd.daily' only return

apache2-bin: /usr/lib/apache2/modules/httpd.exp

The solution is intended to be used for an optimization of the GNOME build tool jhbuild. It should work an a large set of Ubuntu versions.

N0rbert
  • 103,263

1 Answers1

7

The problem is related to the source of files apt-file is matching. It uses the Contents files in /var/lib/apt/lists/, which do not contain the leading /.

# lz4cat /var/lib/apt/lists/de.archive.ubuntu.com_ubuntu_dists_bionic_Contents-amd64.lz4 | grep httpd.exp
usr/lib/apache2/modules/httpd.exp               httpd/apache2-bin
usr/share/doc/lighttpd/expire.txt               universe/web/lighttpd-doc

So just skip the leading / in your regexp and you are fine. I also would recommend to escape dots \. since `.* only means to match any character. In this case it might give you the expected results, but only because there are no other matches.

# apt-file search --regexp 'usr/lib/apache2/modules/httpd\.exp|usr/lib/apt/apt\.systemd\.daily'
apache2-bin: /usr/lib/apache2/modules/httpd.exp
apt: /usr/lib/apt/apt.systemd.daily

The reason why it did work for apache2-bin: /usr/lib/apache2/modules/httpd.exp is because apt-file is taking care of leading slashes and removes them in the search pattern.

But this is only applied to the beginning of the pattern and it does not recognize the or operator and does not remove the leading slash from the second search part. The second search part /usr/lib/apt/apt.systemd.daily does not match because of the missing leading slash in the Contents file.


Addendum

  • as mentioned by N0rbert apt-file --regexp is using Perl Regular Expressions
  • the relevant part from man apt-file outlines the problem of this question in the BUGS, QUIRKS section

    The Contents files do not include a leading slash on paths. This means that /bin/ls is listed as bin/ls in the Contents file. If you are looking for something in a top-level directory, it is often better to omit the leading slash.

    The search algorithm will attempt to work around the leading slash, but it will not work in all cases. As a workaround, try to pull the leading slash to the beginning of regular expressions. For example, use "/(?:usr/bin/vim|sbin/lvm)" instead of "/usr/bin/vim|/sbin/lvm".

Thomas
  • 6,433