【发布时间】:2023-04-09 12:58:02
【问题描述】:
我的问题是我有一个非常大的数据库 (10GB),我想节省尽可能多的时间来搜索它。我有一个 awk 语句正在搜索数据库并根据模式将数据写入另一个文件。
我有一个输入文件,它将作为终端参数变量输入到我的脚本中。其中有几行数据将用作awk 语句的模式。
在数据库中,与模式匹配的所有行都排在彼此旁边,因此基本上,打印后,无需进一步搜索数据库,因为所有内容都已找到。一旦awk 找到第一个模式匹配行,所有其他模式匹配行都在它之后。
这个问题很难用语言来解释,所以我创建了一些示例来说明我的文件、代码和数据库的外观和操作。
通过终端输入的文件如下所示:
group_1
group_2
group_3
...
10GB 的数据库如下所示:
group_1 DATA ...
group_1 DATA ...
group_1 DATA ...
group_2 DATA ...
group_2 DATA ...
group_2 DATA ...
group_2 DATA ...
group_3 DATA ...
group_3 DATA ...
group_3 DATA ...
group_3 DATA ...
...
带有awk 语句的脚本代码如下所示:
IFS=$'\n'
set -f
for var in $(cat < "$1")
do
awk -v seq="$var" '{if (match($1, seq)) {print $0}}' filepath/database > pattern_matched.file
done
对这段代码所做的简单解释是,它接受终端参数变量,在这种情况下是一个文件名,并打开它以供for loop 开始循环。例如,模式group_1 被放置在var 中,然后开始搜索数据库。如果第一列与模式匹配,则将该行保存到文件pattern_matched.file 文件中。
目前,它会搜索整个 10GB 的数据并按预期将数据打印到文件中,但这会浪费很多时间。打印与模式匹配的行后,我想停止 awk 继续搜索数据库并从输入文件转到下一个模式。 group_2 的一个示例行为是 awk 检查数据库的前 3 行并发现没有任何行具有匹配的模式。但是,第 4 行包含该模式,因此它会打印该行和其后的后续模式匹配行。当awk 到达第8 行时,它退出awk 语句,然后for loop 可以迭代到要搜索的下一个模式group_3。
awk '{print $0; exit}' filename
这样的东西不起作用,因为它只打印第一个实例并爆发,我想要一些可以打印所有匹配项的东西,一旦找到下一个非模式匹配,它就会爆发。
提前致谢。
更新:
现在的问题是,下面给出的解决方案是合乎逻辑的。如果它进入 if 语句,它将将该行打印到文件中并迭代到下一行。如果该行不匹配,它将进入 else-if 语句并退出 awk。这对我来说很有意义,但由于某种原因,一旦 flag 变量被第一个匹配行的 if 语句设置为 1,它就会进入 else-if 语句。由于 else-if 条件的计算结果为真,它甚至在扫描下一行之前就退出了。我在awk 语句中的任何地方都使用打印语句确认了这种行为。
这是我的带有打印语句的代码:
awk -v seq="$seqid" '{if(match($1, seq)) {print "matched" ; print $1 ; flag=1} else if (flag) {print "not matched" ; exit}}'
输出这个: weird behavior
【问题讨论】:
-
为什么不添加
-v haveread=0那么你的语句可以是:'{if (match($1, seq)) {print $0; haveread=1} else {haveread == 1 && exit}}'(或类似的使用标志 valraible)这将导致awk到exit在序列之后的第一行它读取的行。在此之前,haveread=0并且在else子句中没有采取任何行动。 -
haveread == 1 && exit是指haveread == 1 ; exit吗?存在一些语法问题。 -
喜欢
awk -v rd=0 '{ if ($1 == seq) {print $1; rd = 1} else {if (rd == 1) exit }}'(使用rd作为标志) -
这几乎可以工作。它打印第一行并自动点击 else-if 并退出。为什么?我不知道,else-if 的定义应该已经停止了它,但我只是在我的代码中确认了它:
awk -v seq="$seqid" -v flag=0 '{if(match($1, seq)) {print $1 ; flag=1 } else {if(flag == 1) exit}}' -
@Lefty 请参阅 awk.freeshell.org/AllAboutGetline 了解为什么不这样做 that。
标签: bash macos awk scripting text-manipulation