使用Shell Awk搜索字符串

使用Shell Awk搜索字符串,shell,scripting,awk,Shell,Scripting,Awk,我有一个字符串: 磁盘“虚拟内存”(也称为“虚拟内存”)已超过95%的最大利用率阈值。 我每次都需要在这个字符串单词中搜索磁盘,如果找到了,我只需要提取“*”中的短语,也称为“*”,并将其放入变量监视器 换句话说,我想搜索并将值放入 MONITOR="'virtual memory' also known as Virtual Memory'" 如何使用awk?这里有一个片段,可以实现您所描述的功能。您应该将其放入$(…)中,以将其分配给$MONITOR变量: $ awk '/The disk

我有一个字符串:

磁盘“虚拟内存”(也称为“虚拟内存”)已超过95%的最大利用率阈值。

我每次都需要在这个字符串单词
中搜索磁盘
,如果找到了,我只需要提取
“*”中的短语,也称为“*”
,并将其放入变量
监视器

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

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

如何使用
awk

这里有一个片段,可以实现您所描述的功能。您应该将其放入
$(…)
中,以将其分配给$MONITOR变量:

$ awk '/The disk '\''.*'\'' also known as '\''.*'\'' has exceeded/ {gsub(/The disk /,"");gsub(/ has exceeded.*$/,"");print}' input.txt
在本例中,awk的两个问题是

  • 它的正则表达式上没有子匹配提取(这就是为什么我的解决方案在主体中使用
    gsub()
    来删除行的第一部分和最后一部分
  • 要在shell脚本中使用awk正则表达式中的引号,需要使用
    '\''
    序列对其进行scape(更多信息)

    • 使用
      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
      更容易用于该任务


      这两个命令都被设置为处理多行数据,这些数据中穿插着不匹配的行(但也适用于包含匹配信息的单行)。只在单独的行上的引号之间打印名称也不是很困难,这样以后就不需要进行太多的剖析(以获得两个空格分隔的名称).

      不要使用反勾号-使用
      $(…)
      符号。诚然,这里没有明显的优势,但一般来说,
      $(…)
      由于各种原因,表示法更优越。我将字符串存储在变量中,而不是将字符串存储在input.txt中variable@Nik删除
      input.txt
      并将变量的内容按如下方式导入:
      echo$THEVARIABLE | awk'…'
      而不是存储在input中。txt它存储在变量$CONTAINER\u字符串中,我想提取匹配值并将其存储在变量$MONTIOR中,下面的表达式现在看起来正常吗?$CONTAINER=`echo“$CONTAINER\u字符串”\124; awk'/磁盘'\'.''.''.'''.''\''也被称为'\'.''''.'''\''已经超过了/{gsub(/磁盘/,'');gsub已经超过了.$/,'';print}''@Nik:如果你的数据在名称周围有双引号,那么这看起来几乎是正确的——我没有测试你的建议,但我发现引号处理中存在一些不一致之处。如果你的数据在名称周围有单引号(如问题所示),它将不起作用。它可能更简单(在处理引号方面)将
      awk
      程序放入文件中(比如
      script.awk
      ),然后使用:
      CONTAINER=$(echo“$CONTAINER\u STRING”| awk-f script.awk)
      。请注意,作业开始时没有
      $
      。Jonathan我也喜欢您使用sed的想法…我将尝试此$Container已经是一个包含字符串的vraible,“磁盘‘虚拟内存’也称为‘虚拟内存’,已超过95%的最大利用率阈值。”@Jonathan$MONITOR=$(echo)“$Container”| sed-n“/磁盘('[^']*'也称为'[^']*').*/s/\1/p”)$MONITOR的预期输出是什么?您不断更改变量名称;
      $Container
      $Container
      是完全不同的。您通常不会写入
      $MONITOR=Something
      ;它会将值
      Something
      分配给名保存在
      $MONITOR
      中的变量。要修改变量本身,您可以编写:
      MONITOR=Something
      。您引用的
      sed
      命令使用
      不带反斜杠;情况取决于您使用的
      sed
      版本。对于大多数版本,匹配失败,因为未转义的括号不是元字符。如果您使用GNU
      sed
      ,它可能(也可能不)将括号解释为元字符。