我正在尝试找出一个 awk 命令/脚本来从一个大文件中提取一段文本。我感兴趣的文件子部分如下:
Board Info: #512
Manufacturer: "Dell Inc."
Product: "0X3D66"
Version: "A02"
Serial: "..CN7016343F00IE."
Chassis Info: #768
主板信息和底盘信息行有 2 个前导空格,而缩进块有 4 个。我不想假设结束行以底盘信息开头(可能是其他内容),而只是依靠以 2 个空格开头的“下一行”。
这:
awk '/^\s{2}Board Info/,/^\s{2}[^B ]/' dump.txt
解决了这个特定的实例,但是如果不是“底盘信息”,结束块行以字母 B 开头(例如,BOM),则不起作用。
如果我使用:
awk '/^\s{2}Board Info/,/^\s{2}\S*/' dump.txt
结尾模式也与“Board Info”行匹配,所以我只获取了该行。如何在不硬编码结尾块(如上所述)的情况下获取缩进的块(前导 4 个空格),并且不依赖结尾模式“下一行恰好以 2 个前导空格开头”?
假设开始后只有带有 4 个空格字符的缩进行,您可以确保至少有一个缩进行,否则不打印任何内容。
不确定是否要打印开始和结束行,但如果您愿意,可以不将它们添加到缓冲区,从而省略打印它们。
您可以更改以下几行:
和:
我会改进你的代码
按照以下方式,让
dump.txt
内容然后
给出输出
解释:我改变了结束条件,要求行以 2 个空格字符开头,后跟任意字母字符,并且(
&&
)不(!
)是 Board Info 行(通过否定开始条件)。(在 GNU Awk 5.3.1 中测试)
您可以添加操作,如果行首至少有 3 个空格字符,则打印以下操作
这将给出以下输出
此
awk
解决方案适用于以下任何版本awk
:解释:
/^ [^[:blank:]]/
匹配以 2 个空格开头、后跟任意非空白字符的行。blk = !blk
:将标志的值切换blk
为1
或0
blk
最后打印一行,如果blk
是1
使用任意 awk:
关于您的原始代码:
/start/,/end/
) 通常比使用标志(在我的代码中)更难正确使用,而且总是更难改进f
,这经常导致代码重复或其他不良软件。有关更多信息,请参阅awk 中 /start/,/end/ 范围表达式是否有用?\s
为简写,[[:space:]]
因此这会使您的代码不可移植,但当您的空格都只是空白字符时,这两种构造都是不必要的。FS
只需对进行微小调整即可获得1/0
不使用模式范围的打印指标: