我不确定&& operator在正则表达式中工作。我要做的是匹配一条线,使它以数字开头,字母'a',下一行以数字开头,字母'b'和下一行......字母'c' 。此abc序列将用作开始读取文件的唯一标识符。
这就是我在awk中的目的。
/(^[0-9]+ .*a)&&\n(^[0-9]+ .*b)&&\n(^[0-9]+ .*c) {
print $0
}
这些正则表达式中只有一个像(^ [0-9] +。* a),但我不知道如何将它们与AND下一行串联起来就是这样。
我的文件就像:
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 :(得分:1)
不,它不起作用。你可以尝试这样的事情:
/(^[0-9]+.*a[^\n]*)\n([0-9]+.*b[^\n]*)\n([0-9]+.*c[^\n]*)/
并且根据需要重复一遍。
[^\n]*
将匹配尽可能多的非换行字符(因此直到换行符)。
答案 1 :(得分:1)
[根据澄清更新。]
一个高阶位是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
答案 2 :(得分:0)
一位朋友为我写了这个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
}
}