awk:基于多种模式的日志处理
awk: log processing based on multiple patterns
我正在处理的日志文件由从不同样本(标识为浮点数 1.1、1.2 ... 1.14)中获取的一些测量值组成,这些测量值按以下格式排列:
Finding intramodel H-bonds
Constraints relaxed by 0.5 angstroms and 20 degrees
Models used:
1.1 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.2 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.3 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.4 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.5 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.6 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.7 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.8 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.9 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.10 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.11 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.12 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.13 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.14 SarsCov2_structure19R_nsp5holo_rep1.pdb
16 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? HIS 163 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 S no hydrogen 3.850 N/A
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? GLU 166 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? GLU 166 H 2.909 2.070
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? CYS 44 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 H 2.798 1.892
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.2/? GLN 189 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.2/A UNL 888 S SarsCov2_structure19R_nsp5holo_rep1.pdb #1.2/? GLN 189 1HE2 3.896 2.916
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/? GLU 166 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/? GLU 166 H 2.673 1.892
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/? CYS 44 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/A UNL 888 H 3.071 2.338
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/? HIS 163 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/A UNL 888 S no hydrogen 3.927 N/A
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/? THR 190 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/A UNL 888 H 3.029 2.173
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.8/? GLN 189 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.8/A UNL 888 S SarsCov2_structure19R_nsp5holo_rep1.pdb #1.8/? GLN 189 2HE2 3.631 2.751
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/? CYS 145 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/? CYS 145 H 2.966 2.210
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/? ARG 188 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/A UNL 888 H 3.067 2.307
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.10/? GLN 189 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.10/A UNL 888 S SarsCov2_structure19R_nsp5holo_rep1.pdb #1.10/? GLN 189 2HE2 3.693 2.786
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.11/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.11/? THR 190 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.11/A UNL 888 H 3.159 2.268
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.12/? GLU 166 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.12/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.12/? GLU 166 H 2.648 1.817
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.13/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.13/? THR 190 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.13/A UNL 888 H 3.176 2.395
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.14/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.14/? PHE 140 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.14/A UNL 888 H 2.833 1.955
我需要打印与样本 (1-14) 相关联的数字,该数字应对应于两种模式的首次出现:“GLU 166 N”和“CYS 44 O”,没有其他模式同一样本内。我需要在与此模式关联的#1.number/? 模式之前的同一行上打印出现的数字。所以在这个例子中,检测到的数字应该是 3(因为关联数字是#1.3/?),其中可以找到两种模式(而不是其他模式!)。最后,如果找不到这两种模式,我想用第一个模式“GLU 166 N”打印对应于样本的数字(就像我的例子)
目前,我的 AWK 解决方案专注于一种基于模式的搜索:查找第一次出现的“GLU 166 N”(如果找不到模式,脚本会打印 1 )。基本上,它会在该行的任何位置查找“模式”,然后从第二个字段打印数字的第二部分(在点之后)":
awk -vn=1 '/GLU 166 N/ {gsub(/.*\.|\/\?/,"",); n=; exit} END {print n}' input.log
根据我们有意义的讨论,你能不能试试:
awk -F# ' # split line on '#' into fields
{
for (i = 1; i <= NF; i++) { # loop over the fields
if (match($i, /^1\.[0-9]+\/\? GLU 166 N/)) {
sub(/^1\./, "", $i); sub(/\/.*/, "", $i)
# extract the number after "1." in $i
if (first == "") first = $i # keep the first found value as a fallback
if ($i in b) { # if the number exists also in b
queue[++qn] = $i # then push it in the queue
}
a[$i]
next
} else if (match($i, /^1\.[0-9]+\/\? CYS 44 O/)) {
sub(/^1\./, "", $i); sub(/\/.*/, "", $i)
if ($i in a) {
queue[++qn] = $i
}
b[$i]
next
} else if (match($i, /^1\.[0-9]+\/\? [A-Z]{3} [0-9]+ [A-Z][A-Z0-9]*/)) {
# analyse other patterns
sub(/^1\./, "", $i); sub(/\/.*/, "", $i)
exclude[$i]
}
}
}
END {
for (i = 1; i <= qn; i++) { # examine the queue in appearance order
j = queue[i] # j is the matched number
if (! (j in exclude)) { # if not found in other patterns
print j # then it is the answer
exit
}
}
if (first == "") print "1" # the default value
else print first # the fallback
}' input.log
- 它搜索名称:
GLU 166 N
、CYS 44 O
和其他物质
以及嵌入在前导形式中的相关数字 #1.<num>/?
.
- 如果
GLU 166 N
和CYS 44 O
的号码相同,则号码为
按出现顺序推入 queue
。
- 我们需要消除也与其他物质一起出现的数字
(除非它出现在同一行中的任何一个之后)。
数组
exclude
存储与这些物质相关的数字。
- 在
END
块中,我们按顺序检查 queue
中的数字。
队列中未包含在 exclude
中的第一个号码将是
用作答案。
- 如果
GLU 166 N
和CYS 44 O
没有相同的数字,第一个
找到的带有 GLU 166 N
的数字用作后备。
- 万一找不到模式,将使用
1
。
[编辑]
这是使用 bash 变量作为搜索模式并将 bash 变量 var
分配给输出的单行代码:
search_pattern1='GLU 166 N'
search_pattern2='CYS 44 O'
var=$(awk -F# -v pat1="$search_pattern1" -v pat2="$search_pattern2" '{for (i = 1; i <= NF; i++) {if (match($i, "^1\.[0-9]+\/\? "pat1)) {sub(/^1\./, "", $i); sub(/\/.*/, "", $i); if (first == "") first = $i; if ($i in b) {queue[++qn] = $i} a[$i]; next} else if (match($i, "^1\.[0-9]+\/\? "pat2)) {sub(/^1\./, "", $i); sub(/\/.*/, "", $i); if ($i in a) {queue[++qn] = $i} b[$i]; next} else if (match($i, /^1\.[0-9]+\/\? [A-Z]{3} [0-9]+ [A-Z][A-Z0-9]*/)) { sub(/^1\./, "", $i); sub(/\/.*/, "", $i); exclude[$i]}}} END {for (i = 1; i <= qn; i++) {j = queue[i]; if (! (j in exclude)) {print j; exit}} if (first == "") print "1"; else print first}' input.log)
[说明]
在 awk 中使用变量作为正则表达式模式时,我们需要注意
报价。在很多情况下我们会使用这样的语句:
if (match([=12=], /regex/)) ...
其中斜杠用作 quotes
来括起正则表达式模式。
引号内的裸词被视为 文字字符串 ,而不是变量
姓名。这就是为什么我们不能将变量名放在引号内。
例如,如果我们说:
if (match($i, /^1\.[0-9]+\/\? pat1/)) ...
单词pat1
不再是变量名。这只是一个文字字符串。
如何解决?我们需要把带引号的字符串和变量
并排以便 awk 将它们连接成一个模式:
if (match($i, "^1\.[0-9]+\/\? "pat1)) ...
- 在这种情况下,我们不能使用斜线引号。相反,我们需要
使用双引号。
- 我们需要添加另一个反斜杠来转义
双引号。
顺便说一下,您的 post “我如何在我的 Awk 脚本中使用 bash 变量?”已
不幸的是,由于 duplicate
而被关闭。然而必不可少的
问题不存在。恐怕审稿人不明白
你想做什么。
我正在处理的日志文件由从不同样本(标识为浮点数 1.1、1.2 ... 1.14)中获取的一些测量值组成,这些测量值按以下格式排列:
Finding intramodel H-bonds
Constraints relaxed by 0.5 angstroms and 20 degrees
Models used:
1.1 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.2 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.3 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.4 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.5 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.6 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.7 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.8 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.9 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.10 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.11 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.12 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.13 SarsCov2_structure19R_nsp5holo_rep1.pdb
1.14 SarsCov2_structure19R_nsp5holo_rep1.pdb
16 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? HIS 163 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 S no hydrogen 3.850 N/A
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? GLU 166 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? GLU 166 H 2.909 2.070
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/? CYS 44 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.1/A UNL 888 H 2.798 1.892
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.2/? GLN 189 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.2/A UNL 888 S SarsCov2_structure19R_nsp5holo_rep1.pdb #1.2/? GLN 189 1HE2 3.896 2.916
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/? GLU 166 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/? GLU 166 H 2.673 1.892
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/? CYS 44 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.3/A UNL 888 H 3.071 2.338
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/? HIS 163 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/A UNL 888 S no hydrogen 3.927 N/A
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/? THR 190 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.4/A UNL 888 H 3.029 2.173
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.8/? GLN 189 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.8/A UNL 888 S SarsCov2_structure19R_nsp5holo_rep1.pdb #1.8/? GLN 189 2HE2 3.631 2.751
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/? CYS 145 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/? CYS 145 H 2.966 2.210
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/? ARG 188 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.9/A UNL 888 H 3.067 2.307
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.10/? GLN 189 NE2 SarsCov2_structure19R_nsp5holo_rep1.pdb #1.10/A UNL 888 S SarsCov2_structure19R_nsp5holo_rep1.pdb #1.10/? GLN 189 2HE2 3.693 2.786
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.11/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.11/? THR 190 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.11/A UNL 888 H 3.159 2.268
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.12/? GLU 166 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.12/A UNL 888 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.12/? GLU 166 H 2.648 1.817
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.13/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.13/? THR 190 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.13/A UNL 888 H 3.176 2.395
SarsCov2_structure19R_nsp5holo_rep1.pdb #1.14/A UNL 888 N SarsCov2_structure19R_nsp5holo_rep1.pdb #1.14/? PHE 140 O SarsCov2_structure19R_nsp5holo_rep1.pdb #1.14/A UNL 888 H 2.833 1.955
我需要打印与样本 (1-14) 相关联的数字,该数字应对应于两种模式的首次出现:“GLU 166 N”和“CYS 44 O”,没有其他模式同一样本内。我需要在与此模式关联的#1.number/? 模式之前的同一行上打印出现的数字。所以在这个例子中,检测到的数字应该是 3(因为关联数字是#1.3/?),其中可以找到两种模式(而不是其他模式!)。最后,如果找不到这两种模式,我想用第一个模式“GLU 166 N”打印对应于样本的数字(就像我的例子)
目前,我的 AWK 解决方案专注于一种基于模式的搜索:查找第一次出现的“GLU 166 N”(如果找不到模式,脚本会打印 1 )。基本上,它会在该行的任何位置查找“模式”,然后从第二个字段打印数字的第二部分(在点之后)":
awk -vn=1 '/GLU 166 N/ {gsub(/.*\.|\/\?/,"",); n=; exit} END {print n}' input.log
根据我们有意义的讨论,你能不能试试:
awk -F# ' # split line on '#' into fields
{
for (i = 1; i <= NF; i++) { # loop over the fields
if (match($i, /^1\.[0-9]+\/\? GLU 166 N/)) {
sub(/^1\./, "", $i); sub(/\/.*/, "", $i)
# extract the number after "1." in $i
if (first == "") first = $i # keep the first found value as a fallback
if ($i in b) { # if the number exists also in b
queue[++qn] = $i # then push it in the queue
}
a[$i]
next
} else if (match($i, /^1\.[0-9]+\/\? CYS 44 O/)) {
sub(/^1\./, "", $i); sub(/\/.*/, "", $i)
if ($i in a) {
queue[++qn] = $i
}
b[$i]
next
} else if (match($i, /^1\.[0-9]+\/\? [A-Z]{3} [0-9]+ [A-Z][A-Z0-9]*/)) {
# analyse other patterns
sub(/^1\./, "", $i); sub(/\/.*/, "", $i)
exclude[$i]
}
}
}
END {
for (i = 1; i <= qn; i++) { # examine the queue in appearance order
j = queue[i] # j is the matched number
if (! (j in exclude)) { # if not found in other patterns
print j # then it is the answer
exit
}
}
if (first == "") print "1" # the default value
else print first # the fallback
}' input.log
- 它搜索名称:
GLU 166 N
、CYS 44 O
和其他物质 以及嵌入在前导形式中的相关数字#1.<num>/?
. - 如果
GLU 166 N
和CYS 44 O
的号码相同,则号码为 按出现顺序推入queue
。 - 我们需要消除也与其他物质一起出现的数字
(除非它出现在同一行中的任何一个之后)。
数组
exclude
存储与这些物质相关的数字。 - 在
END
块中,我们按顺序检查queue
中的数字。 队列中未包含在exclude
中的第一个号码将是 用作答案。 - 如果
GLU 166 N
和CYS 44 O
没有相同的数字,第一个 找到的带有GLU 166 N
的数字用作后备。 - 万一找不到模式,将使用
1
。
[编辑]
这是使用 bash 变量作为搜索模式并将 bash 变量 var
分配给输出的单行代码:
search_pattern1='GLU 166 N'
search_pattern2='CYS 44 O'
var=$(awk -F# -v pat1="$search_pattern1" -v pat2="$search_pattern2" '{for (i = 1; i <= NF; i++) {if (match($i, "^1\.[0-9]+\/\? "pat1)) {sub(/^1\./, "", $i); sub(/\/.*/, "", $i); if (first == "") first = $i; if ($i in b) {queue[++qn] = $i} a[$i]; next} else if (match($i, "^1\.[0-9]+\/\? "pat2)) {sub(/^1\./, "", $i); sub(/\/.*/, "", $i); if ($i in a) {queue[++qn] = $i} b[$i]; next} else if (match($i, /^1\.[0-9]+\/\? [A-Z]{3} [0-9]+ [A-Z][A-Z0-9]*/)) { sub(/^1\./, "", $i); sub(/\/.*/, "", $i); exclude[$i]}}} END {for (i = 1; i <= qn; i++) {j = queue[i]; if (! (j in exclude)) {print j; exit}} if (first == "") print "1"; else print first}' input.log)
[说明]
在 awk 中使用变量作为正则表达式模式时,我们需要注意
报价。在很多情况下我们会使用这样的语句:
if (match([=12=], /regex/)) ...
其中斜杠用作 quotes
来括起正则表达式模式。
引号内的裸词被视为 文字字符串 ,而不是变量
姓名。这就是为什么我们不能将变量名放在引号内。
例如,如果我们说:
if (match($i, /^1\.[0-9]+\/\? pat1/)) ...
单词pat1
不再是变量名。这只是一个文字字符串。
如何解决?我们需要把带引号的字符串和变量 并排以便 awk 将它们连接成一个模式:
if (match($i, "^1\.[0-9]+\/\? "pat1)) ...
- 在这种情况下,我们不能使用斜线引号。相反,我们需要 使用双引号。
- 我们需要添加另一个反斜杠来转义 双引号。
顺便说一下,您的 post “我如何在我的 Awk 脚本中使用 bash 变量?”已
不幸的是,由于 duplicate
而被关闭。然而必不可少的
问题不存在。恐怕审稿人不明白
你想做什么。