所以我有一个 awk 一句话,虽然我理解 什么正在高水平上完成,但我不完全理解 awk 是如何完成我给它的任务的。我要求 awk 仅在满足特定模式时才给我一系列文本。
这是我的 file.txt 的内容:
START
Name: Apple
Kingdom: Plantae
Family: Rosaceae
END
--------------------
START
Name: Cat
Kingdom: Animalia
Family: Felidae
END
--------------------
START
Name: Orange
Kingdom: Plantae
Family: Rutaceae
END
--------------------
START
Name: Dog
Kingdom: Animalia
Family: Canidae
END
--------------------
这是我传递的一行命令:
awk '/START/ {var=""} {var=var ? var ORS $0 : $0} /END/ {if(var~/Plantae/) print var}' file.txt
如果满足条件
var~/Plantae/
,则根据需要返回范围:
07-09-24 13:56:28 terucin @ mean_machine:/home/terucin/Research/Sanity [-130] $ awk '/START/ {var=""} {var=var ? var ORS $0 : $0} /END/ {if(var~/Plantae/) print var}' file.txt
START
Name: Apple
Kingdom: Plantae
Family: Rosaceae
END
START
Name: Orange
Kingdom: Plantae
Family: Rutaceae
END
07-09-24 13:56:33 terucin @ mean_machine:/home/terucin/Research/Sanity [+0] $
所以我知道一些事情:
/START/
= 我的范围的起始标志/END/
= 我的范围的结束标志{var=""}
= 将 var 设置为空字符串condition ? Yay : Boo
= 如果条件为 true,则使用 true 表达式:“Yay”,否则使用 false 表达式:“Boo”我想我知道这里的基础知识:
START
作为我的起始标志(标志打开)和 END
作为我的结束标志(标志关闭)来设置我想要搜索的行的“范围”Plantae
awk 返回标志之间的所有行,包括标志。非常简洁,并且符合我通过 CLI 使用 awk 而不是更强大和更高级的编程语言或方法的场景(诚然相当小众)。
我不知道如何实现这一点。看起来,如果
var
等于 var
(在这种情况下总是成立?也许?),则使用表达式 var ORS $0
。但我的理解如下:
var
等于空ORS
将默认为换行符$0
是正在读入的当前记录(即行),并且是迄今为止唯一被“设置”的值,除了 var
被设置为空所以,显然,幕后还有其他恶作剧正在进行,但我并不能 100% 知道这些恶作剧到底是什么。
我在最后的
print
部分尝试了一些东西,只是为了看看最后设置了什么,我的结论大致是:
ORS
而不是 var
,我只会得到等于带有我的标志的记录数的换行符。因此,如果我使用第一个示例var~/Plantae/
,我会得到四个换行符(两个START
和两个END
行,因为Apple
和Orange
都在其范围内包含模式Plantae
),但如果我只匹配 var~/Apple/
我只得到两个换行符(一个 START
和一个 END
行,因为只有一个范围包含 Apple
)$0
,我会得到END
,这是或者标志关闭,或者可能是正在读取的最终记录,我不确定。这两个选项在功能上可能是相同的(无论如何都在这里打印END
),但也许在标记关闭和正在读取的最终记录之间存在重要的语义差异需要注意?这也返回 END
等于与 if() print
语句匹配的“范围”的数量,如我之前的要点所述(因此 /Apple/
仅返回 END
一次,而 /Plantae/
返回 END
两次)我的问题归结为如何在 awk 中设置所有这些?
var
如何最终包含包括标志在内的整个范围,但 ORS
似乎只保留换行符,而 $0
只是最终标志/最后一条记录(同样,不确定这是哪个)?
如果
等于var
(在这种情况下始终为真?也许?),则使用表达式var
。var ORS $0
你误读了。
=
是赋值,不是比较。所以 var =
正在分配给 var
,它不是将 var
与任何东西进行比较。
它正在对三元表达式的结果进行赋值
var ? var ORS $0 : $0
这意味着如果
var
不为空,则使用var ORS $0
,否则使用$0
。这会生成一个以空格分隔的行列表,并且条件防止在列表中的第一项之前放置空格。