Issue
I'd like to use sed
to modify a Debian control file to change the dependencies of a particular package.
The file contains metadata for several packages, where entry looks like this:
Package: linux-image-generic
Architecture: i386 amd64 armhf arm64 powerpc ppc64el s390x
Section: kernel
Provides: ${dkms:zfs-modules} ${dkms:virtualbox-guest-modules} ${dkms:wireguard-linux-compat-modules}
Depends: ${misc:Depends}, linux-image-${kernel-abi-version}-generic, linux-modules-extra-${kernel-abi-version}-generic [i386 amd64 arm64 powerpc ppc64el s390x], linux-firmware, intel-microcode [amd64 i386], amd64-microcode [amd64 i386]
Recommends: thermald [i386 amd64]
Description: Generic Linux kernel image
This package will always depend on the latest generic kernel image
available.
Package: linux-tools-generic
Architecture: i386 amd64 armhf arm64 powerpc ppc64el s390x
Section: kernel
Provides: linux-tools
Depends: ${misc:Depends}, linux-tools-${kernel-abi-version}-generic
Description: Generic Linux kernel tools
This package will always depend on the latest generic kernel tools
available.
I would like to find the line that matches Package: linux-image-generic
, then modify the following line that matches Depends:
, for instance by performing s/linux-image-/linux-image-unsigned-/
.
Solution
Here's my solution that modifies the Depends:
line, but only within the linux-image-generic
section.
This solution for GNU sed, but a slight modification makes it work for BSD sed, noted below.
sed '/^Package: linux-image-generic$/,/^$/{/^Depends:/ s/linux-image-/linux-image-unsigned-/}' debian/control
It starts with a range address that matches from the beginning of the package metadata up to the blank line after the package block.
/^Package: linux-image-generic$/,/^$/
Then it uses a {}
to apply a command within this range:
/^Depends:/ s/linux-image-/linux-image-unsigned-/
The first part here, /^Depends:/
, is a regular expression address that selects only the line(s) that begin with Depends:
.
Lastly, the s
command performs the substitution on the selected line.
BSD sed (on macOS, etc.) has an additional syntactic rule for function lists { ... }
:
The terminating “}” must be preceded by a newline, and may also be preceded by white space.
We need to insert a newline before the }
, for example by using the $'\n'
ANSI-C string in Bash:
sed '/^Package: linux-image-generic$/,/^$/{/^Depends:/ s/linux-image-/linux-image-unsigned-/'$'\n''}' debian/control
As an aside, the path to finding this solution was to research sed
commands that operate on other file formats with similar syntaxes, like INI files.
Answered By - rgov Answer Checked By - Senaida (WPSolving Volunteer)