使用Shell Awk搜索字符串

时间:2013-02-11 14:57:40

标签: shell scripting awk

我有一个字符串:

The disk 'virtual memory' also known as 'Virtual Memory' has exceeded the maximum utilization threshold of 95 Percent.

我需要每次都在这个字符串中搜索The disk,如果找到,那么我只需要在'*' also known as '*'中提取短语并将其放入变量MONITOR

换句话说,我想搜索并将值放到

MONITOR="'virtual memory' also known as Virtual Memory'"

如何使用awk

进行操作

2 个答案:

答案 0 :(得分:1)

这是一个执行您所描述内容的片段。您应该将其放在$(...)中以将其分配给$ MONITOR变量:

$ awk '/The disk '\''.*'\'' also known as '\''.*'\'' has exceeded/ {gsub(/The disk /,"");gsub(/ has exceeded.*$/,"");print}' input.txt

在这种情况下,awk的两个问题是

  • 它的正则表达式没有子匹配提取(这就是为什么我的解决方案在正文中使用gsub()来摆脱行的第一部分和最后一部分。
  • 要在shell脚本中使用awk regex中的引号,您需要使用'\''序列来搜索它(更多信息here

答案 1 :(得分:0)

使用sed而不是awk

可能会更容易一些
string="The disk 'virtual memory' also known as 'Virtual Memory' has exceeded the maximum utilization threshold of 95 Percent."

MONITOR=$(echo "$string" | sed -n "/The disk \('[^']*' also known as '[^']*'\) .*/s//\1/p")

如果需要awk,则:

MONITOR=$(echo "$string" | awk "/The disk '[^']*' also known as '[^']*'/ {
                                print \$3, \$4, \$5, \$6, \$7, \$8, \$9; } {}')

空大括号{}匹配任何行并且不打印任何内容,因此awk仅处理与正则表达式匹配的行。请注意,这假设每个磁盘都有一个名称,其中包含两个单词。您需要使用更强大的处理(例如gsub函数)来执行基于正则表达式的替换。这不是awk的强项; sed更容易用于该任务。

这两个命令都设置为处理散布有不匹配行的多行数据(但也适用于包含匹配信息的单行)。在单独的行上打印引号之间的名称也不是很困难,因此您之后可以进行较少的解剖(以获得两个以空格分隔的名称)。