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-/
.
3
Answers
Here's my solution that modifies the
Depends:
line, but only within thelinux-image-generic
section.This solution for GNU sed, but a slight modification makes it work for BSD sed, noted below.
It starts with a range address that matches from the beginning of the package metadata up to the blank line after the package block.
Then it uses a
{}
to apply a command within this range:The first part here,
/^Depends:/
, is a regular expression address that selects only the line(s) that begin withDepends:
.Lastly, the
s
command performs the substitution on the selected line.BSD sed (on macOS, etc.) has an additional syntactic rule for function lists
{ ... }
:We need to insert a newline before the
}
, for example by using the$'n'
ANSI-C string in Bash: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.The
sed
solution you found is perfect. For completeness, with GNUawk
instead ofsed
:If the input record separator (
RS
) is the empty string records are separated by empty lines. So each section of your file is a record.gensub
does the substitution.This might work for you (GNU sed):
Find line containing
Package: linux-image-generic
then continue reading lines until one containingDepends:
and substitutelinux-image-
withlinux-image-unsigned-
.N.B. This assumes the package stanza contains
Depends:
, if not, then: