如何在多行模式和第二个字符串模式之间提取多行
How to extract multiple lines between a multi-line pattern and a second string pattern
目标是在基于 reprepro 的 deb 存储库中获取源包的版本。
由于源包的跟踪在 reprepro 中仍处于试验阶段,list 命令与 --list-format 选项存在问题,因此不能用于此用例。
打印出有关跟踪源包的所有信息的命令输出的摘录是:
...
Distribution: buster
Source: linux-latest
Version: 102
Files:
pool/stable/l/linux-latest/linux-doc_4.19+102_all.deb a 2
pool/stable/l/linux-latest/linux-headers-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-cloud-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-rt-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64-dbg_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64-dbg_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64-dbg_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-perf_4.19+102_all.deb a 2
pool/stable/l/linux-latest/linux-source_4.19+102_all.deb a 2
Distribution: buster
Source: linux-latest
Version: 103
Files:
pool/stable/l/linux-latest/linux-doc_4.19+103_all.deb a 0
pool/stable/l/linux-latest/linux-headers-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-cloud-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-rt-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64-dbg_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64-dbg_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64-dbg_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-perf_4.19+103_all.deb a 2
pool/stable/l/linux-latest/linux-source_4.19+103_all.deb a 2
...
这里的目标是通过提取以下之间的所有行来获取例如 linux-latest
源包的版本,例如使用二进制包名称 linux-source_4.19+103_all.deb
1) 多行模式:
Distribution: buster
Source: linux-latest
2) 字符串模式:
linux-source_4.19+103_all.deb
分发名称、源包名称和二进制包名称是可变的,因此捕获的行数是可变的,但基本布局保持不变。
出于同样的原因,这里似乎不能使用 pcre2grep --multiline
。
我看不到通过 awk 或 sed 使用多行模式的方法,尽管必须有一种方法,至少对于 awk。
其他 Whosebug 答案似乎不适用于此处:
有什么建议吗?
尚不完全清楚您要做什么,但我 认为 您是说要在记录中出现特定字符串时打印版本值。如果是这样,那就是:
$ awk -v str='linux-source_4.19+103_all.deb' -F': *' '{f[]=} index([=10=],str){print f["Version"]}' file
103
如果您还想测试特定的发行版和来源,那只是一个调整:
$ awk -v str='linux-source_4.19+103_all.deb' -v dist='buster' -v src='linux-latest' -F': *' '
{ f[] = }
(f["Distribution"]==dist) && (f["Source"]==src) && index([=11=],str) { print f["Version"] }
' file
103
如果您需要不同的东西,请编辑您的问题以阐明您的要求。
这可能适合您 (GNU sed):
sed '/^Distribution: buster$/{:a;N;/\n\s*$/!ba;/^Source: linux-latest$/Ms/.*Version: \(\S\+\).*//p};d' file
收集特定 Distribution
的行并使用模式匹配然后提取所需的 Version
.
这可以推广到任何 Distribution
行集合:
sed '/^Distribution/{:a;N;/\n$/!ba;/linux-source_4.19+103_all.deb/s/.*Version: \(\S\+\).*//p};d' file
因此第一个解可以写成:
sed '/^Distribution/{:a;N;/\n$/!ba;/Distribution: buster\nSource: linux-latest/s/.*Version: \(\S\+\).*//p};d' file
或者如果您愿意:
sed '/^Distribution/{:a;N;/\n$/!ba;/^Distribution: buster$/M!b;/^Source: linux-latest$/M!b;s/.*Version: \(\S\+\).*//p};d' file
N.B。必须注意引用匹配字符串中可能存在的任何元字符,即必须引用 []*.
等字符,例如[
变为 \[
.
目标是在基于 reprepro 的 deb 存储库中获取源包的版本。
由于源包的跟踪在 reprepro 中仍处于试验阶段,list 命令与 --list-format 选项存在问题,因此不能用于此用例。
打印出有关跟踪源包的所有信息的命令输出的摘录是:
...
Distribution: buster
Source: linux-latest
Version: 102
Files:
pool/stable/l/linux-latest/linux-doc_4.19+102_all.deb a 2
pool/stable/l/linux-latest/linux-headers-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-cloud-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-rt-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64-dbg_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64-dbg_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64-dbg_4.19+102_amd64.deb b 1
pool/stable/l/linux-latest/linux-perf_4.19+102_all.deb a 2
pool/stable/l/linux-latest/linux-source_4.19+102_all.deb a 2
Distribution: buster
Source: linux-latest
Version: 103
Files:
pool/stable/l/linux-latest/linux-doc_4.19+103_all.deb a 0
pool/stable/l/linux-latest/linux-headers-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-cloud-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-headers-rt-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-amd64-dbg_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-cloud-amd64-dbg_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-image-rt-amd64-dbg_4.19+103_amd64.deb b 1
pool/stable/l/linux-latest/linux-perf_4.19+103_all.deb a 2
pool/stable/l/linux-latest/linux-source_4.19+103_all.deb a 2
...
这里的目标是通过提取以下之间的所有行来获取例如 linux-latest
源包的版本,例如使用二进制包名称 linux-source_4.19+103_all.deb
1) 多行模式:
Distribution: buster
Source: linux-latest
2) 字符串模式:
linux-source_4.19+103_all.deb
分发名称、源包名称和二进制包名称是可变的,因此捕获的行数是可变的,但基本布局保持不变。
出于同样的原因,这里似乎不能使用 pcre2grep --multiline
。
我看不到通过 awk 或 sed 使用多行模式的方法,尽管必须有一种方法,至少对于 awk。
其他 Whosebug 答案似乎不适用于此处:
有什么建议吗?
尚不完全清楚您要做什么,但我 认为 您是说要在记录中出现特定字符串时打印版本值。如果是这样,那就是:
$ awk -v str='linux-source_4.19+103_all.deb' -F': *' '{f[]=} index([=10=],str){print f["Version"]}' file
103
如果您还想测试特定的发行版和来源,那只是一个调整:
$ awk -v str='linux-source_4.19+103_all.deb' -v dist='buster' -v src='linux-latest' -F': *' '
{ f[] = }
(f["Distribution"]==dist) && (f["Source"]==src) && index([=11=],str) { print f["Version"] }
' file
103
如果您需要不同的东西,请编辑您的问题以阐明您的要求。
这可能适合您 (GNU sed):
sed '/^Distribution: buster$/{:a;N;/\n\s*$/!ba;/^Source: linux-latest$/Ms/.*Version: \(\S\+\).*//p};d' file
收集特定 Distribution
的行并使用模式匹配然后提取所需的 Version
.
这可以推广到任何 Distribution
行集合:
sed '/^Distribution/{:a;N;/\n$/!ba;/linux-source_4.19+103_all.deb/s/.*Version: \(\S\+\).*//p};d' file
因此第一个解可以写成:
sed '/^Distribution/{:a;N;/\n$/!ba;/Distribution: buster\nSource: linux-latest/s/.*Version: \(\S\+\).*//p};d' file
或者如果您愿意:
sed '/^Distribution/{:a;N;/\n$/!ba;/^Distribution: buster$/M!b;/^Source: linux-latest$/M!b;s/.*Version: \(\S\+\).*//p};d' file
N.B。必须注意引用匹配字符串中可能存在的任何元字符,即必须引用 []*.
等字符,例如[
变为 \[
.