使用 sed 修改文档特定部分中的一行
Modify a line in a particular section of a document with sed
我想使用 sed
修改 Debian control file 来更改特定软件包的依赖项。
该文件包含多个包的元数据,其中条目如下所示:
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.
我想找到匹配 Package: linux-image-generic
的行,然后修改下面匹配 Depends:
的行,例如通过执行 s/linux-image-/linux-image-unsigned-/
.
这是我修改 Depends:
行的解决方案,但仅限于 linux-image-generic
部分。
此解决方案适用于 GNU sed,但稍作修改使其适用于 BSD sed,如下所述。
sed '/^Package: linux-image-generic$/,/^$/{/^Depends:/ s/linux-image-/linux-image-unsigned-/}' debian/control
它以 range address 开头,匹配从包元数据的开头到包块之后的空行。
/^Package: linux-image-generic$/,/^$/
然后它使用 {}
在 这个范围内应用命令 :
/^Depends:/ s/linux-image-/linux-image-unsigned-/
此处的第一部分 /^Depends:/
是一个 regular expression address,仅选择以 Depends:
.
开头的行
最后,s
command 对所选行执行替换。
BSD sed(在 macOS 等上)有一个额外的函数列表语法规则 { ... }
:
The terminating “}” must be preceded by a newline, and may also be preceded by white space.
我们需要在}
之前插入一个换行符,例如在Bash中使用$'\n'
ANSI-C string:
sed '/^Package: linux-image-generic$/,/^$/{/^Depends:/ s/linux-image-/linux-image-unsigned-/'$'\n''}' debian/control
顺便说一句,找到此解决方案的途径是研究 sed
对具有类似语法的其他文件格式进行操作的命令,例如 INI files.
您找到的sed
解决方案是完美的。为了完整起见,使用 GNU awk
而不是 sed
:
awk -v RS= -v ORS='\n\n' '/^Package: linux-image-generic/ {
[=10=] = gensub(/(\nDepends:[^\n]*linux-image-)/,"&unsigned-",1)} 1' file
如果输入的记录分隔符(RS
)为空字符串,则记录由空行分隔。因此,文件的每个部分都是一条记录。 gensub
进行替换。
这可能适合您 (GNU sed):
sed '/Package: linux-image-generic/{:a;n;/Depends:/!ba;s/linux-image-/&unsigned-/}' file
查找包含 Package: linux-image-generic
的行然后继续阅读直到包含 Depends:
的行并将 linux-image-
替换为 linux-image-unsigned-
.
N.B。这假定包节包含 Depends:
,如果不包含,则:
sed -E '/Package:/{h;:a;n;/Package:/{h;ba};/Depends/!ba;G
s/(linux-image-)(.*)\n.*Package: linux-image-generic/unsigned-/}' file
我想使用 sed
修改 Debian control file 来更改特定软件包的依赖项。
该文件包含多个包的元数据,其中条目如下所示:
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.
我想找到匹配 Package: linux-image-generic
的行,然后修改下面匹配 Depends:
的行,例如通过执行 s/linux-image-/linux-image-unsigned-/
.
这是我修改 Depends:
行的解决方案,但仅限于 linux-image-generic
部分。
此解决方案适用于 GNU sed,但稍作修改使其适用于 BSD sed,如下所述。
sed '/^Package: linux-image-generic$/,/^$/{/^Depends:/ s/linux-image-/linux-image-unsigned-/}' debian/control
它以 range address 开头,匹配从包元数据的开头到包块之后的空行。
/^Package: linux-image-generic$/,/^$/
然后它使用 {}
在 这个范围内应用命令 :
/^Depends:/ s/linux-image-/linux-image-unsigned-/
此处的第一部分 /^Depends:/
是一个 regular expression address,仅选择以 Depends:
.
最后,s
command 对所选行执行替换。
BSD sed(在 macOS 等上)有一个额外的函数列表语法规则 { ... }
:
The terminating “}” must be preceded by a newline, and may also be preceded by white space.
我们需要在}
之前插入一个换行符,例如在Bash中使用$'\n'
ANSI-C string:
sed '/^Package: linux-image-generic$/,/^$/{/^Depends:/ s/linux-image-/linux-image-unsigned-/'$'\n''}' debian/control
顺便说一句,找到此解决方案的途径是研究 sed
对具有类似语法的其他文件格式进行操作的命令,例如 INI files.
您找到的sed
解决方案是完美的。为了完整起见,使用 GNU awk
而不是 sed
:
awk -v RS= -v ORS='\n\n' '/^Package: linux-image-generic/ {
[=10=] = gensub(/(\nDepends:[^\n]*linux-image-)/,"&unsigned-",1)} 1' file
如果输入的记录分隔符(RS
)为空字符串,则记录由空行分隔。因此,文件的每个部分都是一条记录。 gensub
进行替换。
这可能适合您 (GNU sed):
sed '/Package: linux-image-generic/{:a;n;/Depends:/!ba;s/linux-image-/&unsigned-/}' file
查找包含 Package: linux-image-generic
的行然后继续阅读直到包含 Depends:
的行并将 linux-image-
替换为 linux-image-unsigned-
.
N.B。这假定包节包含 Depends:
,如果不包含,则:
sed -E '/Package:/{h;:a;n;/Package:/{h;ba};/Depends/!ba;G
s/(linux-image-)(.*)\n.*Package: linux-image-generic/unsigned-/}' file