Python 如何检查属于可变大小行块的多行上的多个条件并返回主线
基本上我的文本文件是这样的Python 如何检查属于可变大小行块的多行上的多个条件并返回主线,python,python-3.x,awk,sed,Python,Python 3.x,Awk,Sed,基本上我的文本文件是这样的 **A: lorem ipsum verade(unique)** a: asd b: asd c: alsd d: def **B: korem ipsum vladmir(unique)** c: fdh e: asd **C: lorum ipsum vladmir(unique)** a: asd b: asd d: def e: asd 如图所示,假设example.txt有3个主要条目(A、B、C),其中包含多个数据。 我的
**A: lorem ipsum verade(unique)**
a: asd
b: asd
c: alsd
d: def
**B: korem ipsum vladmir(unique)**
c: fdh
e: asd
**C: lorum ipsum vladmir(unique)**
a: asd
b: asd
d: def
e: asd
如图所示,假设example.txt有3个主要条目(A、B、C),其中包含多个数据。
我的问题是,如果A:asd和d:def,我可以检查A的多个条件吗?例如,我想要A、B、C的所有条目。所以输出应该是A和C。
基本上,我想知道如何检查多条线路,同时提前跟踪线路。
我希望我说得很清楚。请记住这是一个巨大的文件,因此如果可能,需要避免多次循环。在AWK中:
如果要搜索的字符串分别分配给“v1”和“v2”
$ v2="a: asd"; v1="d: def"
$ awk -v v1="$v1" -v v2="$v2" '/\*\*.*\*\*/{s=substr($0,match($0,/\*\*.\:/)+2,1);next}{a[s]=a[s] $0}END{for(i in a)if(match(a[i],v1)&&match(a[i],v2))print i}' test.txt
A
C
一个衬垫可按以下步骤展开:
$ cat awk-script
/\*\*.*\*\*/{
s=substr($0,match($0,/\*\*.\:/)+2,1);
next
}
{
a[s]=a[s] $0
}
END{
for(i in a)
if(match(a[i],v1)&&match(a[i],v2))
print i
}
$ awk -v v1="$v1" -v v2="$v2" -f awk-script test.txt
A
C
简要说明
:搜索主要条目/\*\*.*\*/
:将主条目的值分配给's's=substr($0,match($0,/\*\.\:/)+2,1)
:分配属于每个主条目的记录a[s]=a[s]$0
:检查“v1”和“v2”是否与每个主条目中的值匹配match(a[i],v1)和&match(a[i],v2)
***
开头的行表示(或***
带有一些前导空格)。为了打印集合,它必须包含字符串a:asd
和d:def
,否则它是一个虚假集合,最好忘记。所有其他行都可以附加到当前集合。使用python:
创建空列表以存储选定的块:
块=[]
创建标记以记录是否找到模式('asd'、'def')
s_asd,s_def=假,假
为当前块创建empy列表:
blck=[]
逐行阅读并检查:
如果行包含**和s_asd,s_def为真,则将当前块附加到“块”中。
然后清除当前块('blck'),并将标志设置为False。
如果该行不包含**,请检查“asd”或“def”模式,并设置相应的标志。
将当前行追加到“blck”
在循环结束时,您必须再次检查标志,并在必要时将“blck”附加到“blocks”
代码示例:
...
line=line.strip()
if line[:2]=="**" and line[-2:]=="**":
if s_asd and s_def:
blocks.append(blck)
s_asd,s_def=False,False
blck=[]
...
您如何确定主条目是什么?大写字符后跟冒号?其他条目是否总是采用
格式?是的,可用于此目的或特定关键字。您预期的输出是什么?仅以A&C为例?是的,这就足够了。但这种情况下的问题是,如果这里有多个相同的条目,那么计数器也会增加,但我希望精确匹配,就像参数A和d都应该在那里一样……因此,为参数A和参数b创建两个“计数器”
...
line=line.strip()
if line[:2]=="**" and line[-2:]=="**":
if s_asd and s_def:
blocks.append(blck)
s_asd,s_def=False,False
blck=[]
...
$ cat tst.awk
match($0,/[[:upper:]]:/) { prt(); key=substr($0,RSTART,1) }
{ rec = rec $0 ORS }
END { prt() }
function prt() {
if ( (rec ~ /a: asd/) && (rec ~ /d: def/) ) {
print key
}
rec = key = ""
}
$ awk -f tst.awk file
A
C