【问题标题】:Search String using Shell Awk使用 Shell awk 搜索字符串
【发布时间】:2013-01-26 16:52:44
【问题描述】:

我有一个字符串:

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

【问题讨论】:

    标签: shell scripting awk


    【解决方案1】:

    这是一个符合您描述的 sn-p。你应该把它放在$(...) 中以将它分配给 $MONITOR 变量:

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

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

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

    【讨论】:

    • 不要使用反引号——改用$(...) 表示法。诚然,这里并没有那么明显的优势,但总的来说,$(...) 表示法由于各种原因更胜一筹。
    • 我没有在 input.txt 中有字符串,而是在变量中有字符串
    • 我没有输入.txt,而是将字符串存储在变量中
    • @Nik 删除 input.txt 并像这样通过管道传输变量的内容:echo $THEVARIABLE | awk '...'
    【解决方案2】:

    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 中,而是存储在变量 $CONTAINER_STRING 中,我想提取匹配值并将其存储在变量 $MONTIOR 中,下面的表达式现在看起来还好吗? $CONTAINER=`echo "$CONTAINER_STRING" | awk '/磁盘'\''.*'\''也称为'\''。*'\''已超出/ {gsub(/磁盘/,"");gsub(/已超出.* $/,"");打印}''
    • @Nik:如果您的数据在名称周围有双引号,那么这看起来几乎是正确的——我没有测试您的建议,但我发现引号处理中存在一些不一致之处。如果您的数据在名称周围有单引号(如问题所示),它将不起作用。将awk 程序放在一个文件中(比如script.awk)然后使用它可能更简单(就处理引号而言):CONTAINER=$(echo "$CONTAINER_STRING" | awk -f script.awk)。请注意,作业开头没有$
    • 乔纳森我也喜欢你使用 sed 的想法......我会试试这个
    • $Container 已经是一个包含字符串的变量,“磁盘‘虚拟内存’也称为‘虚拟内存’已超过最大利用率阈值 95%。” @Jonathan $MONITOR=$(echo "$Container" | sed -n "/磁盘 ('[^']*' 也称为 '[^']*') .*/s//\1/p" ) $MONITOR 的预期输出是什么?
    • 你不断地改变变量名; $Container$CONTAINER 完全不同。你仍然不会正常写$MONITOR=Something;将值Something 分配给名称保存在$MONITOR 中的变量。要修改变量本身,请编写:MONITOR=Something。您引用的sed 命令使用(),不带反斜杠;会发生什么取决于您使用的sed 的版本。对于大多数版本,匹配失败,因为未转义的括号不是元字符。如果您使用 GNU sed,它可能(也可能不会)将括号解释为元字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 2012-05-11
    • 2013-05-09
    • 2015-12-21
    • 2020-02-23
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多