Python 匹配AWK中多行的正则表达式&&;操作人员
我不确定&&运算符是否在正则表达式中工作。我想做的是匹配一行,使它以一个数字开头,有字母“a”,下一行以一个数字开头,有字母“b”和下一行。。。字母“c”。此abc序列将用作开始读取文件的唯一标识符 这就是我在awk的目的Python 匹配AWK中多行的正则表达式&&;操作人员,python,regex,parsing,awk,Python,Regex,Parsing,Awk,我不确定&&运算符是否在正则表达式中工作。我想做的是匹配一行,使它以一个数字开头,有字母“a”,下一行以一个数字开头,有字母“b”和下一行。。。字母“c”。此abc序列将用作开始读取文件的唯一标识符 这就是我在awk的目的 /(^[0-9]+ .*a)&&\n(^[0-9]+ .*b)&&\n(^[0-9]+ .*c) { print $0 } 这些正则表达式中只有一个类似于(^[0-9]+.*a),但我不确定如何将它们串在一起,下一行就是这个 我的文件如下:
/(^[0-9]+ .*a)&&\n(^[0-9]+ .*b)&&\n(^[0-9]+ .*c) {
print $0
}
这些正则表达式中只有一个类似于(^[0-9]+.*a),但我不确定如何将它们串在一起,下一行就是这个
我的文件如下:
JUNK UP HERE NOT STARTING WITH NUMBER
1 a 0.110 0.069
2 a 0.062 0.088
3 a 0.062 0.121
4 b 0.062 0.121
5 c 0.032 0.100
6 d 0.032 0.100
7 e 0.032 0.100
我想要的是:
3 a 0.062 0.121
4 b 0.062 0.121
5 c 0.032 0.100
6 d 0.032 0.100
7 e 0.032 0.100
不,它不起作用。您可以尝试以下方法:
/(^[0-9]+.*a[^\n]*)\n([0-9]+.*b[^\n]*)\n([0-9]+.*c[^\n]*)/
并根据你的需要重复这句话
[^\n]*
将尽可能多地匹配一行中的非换行符字符(直到换行符)。[根据说明更新。]
一个重要的方面是Awk是一种面向行的语言,所以您实际上无法对跨行进行常规模式匹配。这样做的通常方法是分别匹配每一行,然后让后面的子句/语句确定是否所有正确的部分都匹配
这里我要做的是在一行的第二个字段中查找a
,在另一行的第二个字段中查找b
,在第三行的第二个字段中查找c
。在前两种情况下,我隐藏了行的内容以及它发生在哪个行号上。当第三行匹配时,我们还没有找到整个序列,我返回并检查其他两行是否存在,是否有可接受的行号。如果一切正常,我打印出缓冲的前几行,并设置一个标志,指示其他所有内容都应该打印
以下是脚本:
$2 == "a" { a = $0; aLine = NR; }
$2 == "b" { b = $0; bLine = NR; }
$2 == "c" && !keepPrinting {
if ((bLine == (NR - 1)) && (aLine == (NR - 2))) {
print a;
print b;
keepPrinting = 1;
}
}
keepPrinting { print; }
这是我测试过的一个文件:
JUNK UP HERE NOT STARTING WITH NUMBER
1 a 0.110 0.069
2 a 0.062 0.088
3 a 0.062 0.121
4 b 0.062 0.121
5 c 0.032 0.100
6 d 0.032 0.100
7 e 0.032 0.100
8 a 0.099 0.121
9 b 0.098 0.121
10 c 0.097 0.100
11 x 0.000 0.200
以下是我运行它时得到的结果:
$ awk -f blort.awk blort.txt
3 a 0.062 0.121
4 b 0.062 0.121
5 c 0.032 0.100
6 d 0.032 0.100
7 e 0.032 0.100
8 a 0.099 0.121
9 b 0.098 0.121
10 c 0.097 0.100
11 x 0.000 0.200
一个朋友为我写了这个awk程序。它是一台状态机。它是有效的
#!/usr/bin/awk -f
BEGIN {
# We start out in the "idle" state.
state = "idle"
}
/^[0-9]+[[:space:]]+q/ {
# Everytime we encounter a "# q" we either print it or go to the
# "q_found" state.
if (state != "printing") {
state = "q_found"
line_q = $0
}
}
/^[0-9]+[[:space:]]+r/ {
# If we are in the q_found state and "# r" immediate follows,
# advance to the r_found state. Else, return to "idle" and
# wait for the "# q" to start us off.
if (state == "q_found") {
state = "r_found"
line_r = $0
} else if (state != "printing") {
state = "idle"
}
}
/^[0-9]+[[:space:]]+l/ {
# If we are in the r_found state and "# l" immediate follows,
# advance to the l_found state. Else, return to "idle" and
# wait for the "# q" to start us off.
if (state == "r_found") {
state = "l_found"
line_l = $0
} else if (state != "printing") {
state = "idle"
}
}
/^[0-9]+[[:space:]]+i/ {
# If we are in the l_found state and "# i" immediate follows,
# we're ready to start printing. First, display the lines we
# squirrelled away then move to the "printing" state. Else,
# go to "idle" and wait for the "# q" to start us off.
if (state == "l_found") {
state = "printing"
print line_q
print line_r
print line_l
line = 0
} else if (state != "printing") {
state = "idle"
}
}
/^[0-9]+[[:space:]]+/ {
# If in state "printing", print 50 lines then stop printing
if (state == "printing") {
if (++line < 48) print
}
}
#/usr/bin/awk-f
开始{
#我们开始时处于“空闲”状态。
state=“空闲”
}
/^[0-9]+[:空格:]+q/{
#每次我们遇到一个“#q”,我们要么打印它,要么去
#“q_发现”状态。
如果(状态!=“打印”){
state=“找到了q_”
行_q=$0
}
}
/^[0-9]+[:空格:]+r/{
#如果我们处于q#u found状态,并且“#r”紧跟其后,
#前进到r_found状态。否则,返回“空闲”并
#等待“#q”开始我们的旅程。
如果(状态==“找到q_”){
state=“r\u已找到”
行r=$0
}否则如果(状态!=“打印”){
state=“空闲”
}
}
/^[0-9]+[:空格:]+l/{
#如果我们处于r#u found状态,紧接着是“#l”,
#前进到l_found状态。否则,返回“空闲”并
#等待“#q”开始我们的旅程。
如果(状态==“已找到r_”){
state=“l_已找到”
行_l=$0
}否则如果(状态!=“打印”){
state=“空闲”
}
}
/^[0-9]+[:空格:]+i/{
#如果我们处于l#u found状态,紧接着是“#i”,
#我们准备好开始打印了。首先,显示我们要打印的行
#然后移动到“打印”状态。否则,
#转到“空闲”,等待“#q”启动我们。
如果(状态==“找到l_”){
state=“打印”
打印行
打印行
打印行
直线=0
}否则如果(状态!=“打印”){
state=“空闲”
}
}
/^[0-9]+[:空格:]+/{
#如果处于“打印”状态,打印50行,然后停止打印
如果(状态=“打印”){
如果(++行<48)打印
}
}
没有。谢谢你告诉我,尽管只是为了好玩,试着在所有三个实例中将[^\n]
替换为
。不,我的意思是删除[^\n]
,然后使用
。。。不幸的是,如果这还不行,我今天就没主意了。你怎么把多个换行符转换成$0
?默认情况下,awk
一次只读取一行,因此$0
从不包含您要查找的新行。啊,好的。我不熟悉awk
,所以我只是假设他想要的正则表达式将作为一个字符串处理他给定的输入。对于你的情况,因为你的“子句”(你想要的三个条件)不重叠,你根本不需要任何操作符,只需按照@m.buettner建议的方式“吃掉”行的其余部分。在条件确实重叠的情况下,例如如果要检查一行是否包含符号和数字(但不知道顺序),则可以使用所谓的“先行断言”来实现这种匹配。我知道的唯一先行断言是python中的next()函数。我在下面的回答中尝试了它。我不熟悉Python,但我谈论的是lookahead和lookahead构造,我知道Python支持这两种构造:。这与我想要的类似。我应该提到abc将是我文件中唯一的序列。我将把它作为阅读的起点。所以,我想从你的测试文件输出的是A,B,C,D,E,A,B,C,席的线更新我的答案,根据你的意见。从学术角度来看,您发布的状态机解决方案很有趣,但也许像这样的解决方案更实用?谢谢danfuzz。对我来说,向老板解释脚本比解释状态机更容易。我所做的就是添加{if((keepPrinting>0)&&(++keepPrinting)