如何在多行模式和第二个字符串模式之间提取多行

问题描述 投票:1回答:2

目标是在基于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。

其他stackoverflow答案似乎不适用于此:

有什么建议吗?

awk sed pattern-matching multiline
2个回答
1
投票

目前还不完全清楚你要做什么,但我认为你说你想在记录中出现特定字符串时打印版本值。如果只是这样:

$ awk -v str='linux-source_4.19+103_all.deb' -F': *' '{f[$1]=$2} index($0,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[$1] = $2 }
    (f["Distribution"]==dist) && (f["Source"]==src) && index($0,str) { print f["Version"] }
' file
103

如果您需要不同的东西,请编辑您的问题以阐明您的要求。


0
投票

这可能适合你(GNU sed):

sed '/^Distribution: buster$/{:a;N;/\n\s*$/!ba;/^Source: linux-latest$/Ms/.*Version: \(\S\+\).*/\1/p};d' file

收集特定Distribution的线条并使用模式匹配然后提取所需的Version

这可以推广到任何Distribution系列:

sed '/^Distribution/{:a;N;/\n$/!ba;/linux-source_4.19+103_all.deb/s/.*Version: \(\S\+\).*/\1/p};d' file

因此可以写出第一个解决方案:

sed '/^Distribution/{:a;N;/\n$/!ba;/Distribution: buster\nSource: linux-latest/s/.*Version: \(\S\+\).*/\1/p};d' file

或者如果您愿意:

sed '/^Distribution/{:a;N;/\n$/!ba;/^Distribution: buster$/M!b;/^Source: linux-latest$/M!b;s/.*Version: \(\S\+\).*/\1/p};d' file

注:必须注意引用可能在匹配字符串中的任何元字符,例如[]*.之类的字符必须引用,例如[成为\[

© www.soinside.com 2019 - 2024. All rights reserved.