Bash Shell脚本-匹配特定命名字段中的值

Bash Shell脚本-匹配特定命名字段中的值,bash,shell,unix,Bash,Shell,Unix,例如,假设我们有一行: RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail 在这里,测试、从属、所有者、时间和状态是不同的属性。 属性的数量可能会有所不同,例如,可能存在另一个属性,如category=xyz,或者某些属性可能不存在 我正在寻找一个正则表达式,如果“owner=”包含一个特定的所有者,比如“own2”,则该正则表达式匹配。此外,此正则表达式不应与行中的其他引用相匹配。例如,行可以

例如,假设我们有一行:

RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail
在这里,测试、从属、所有者、时间和状态是不同的属性。 属性的数量可能会有所不同,例如,可能存在另一个属性,如category=xyz,或者某些属性可能不存在

我正在寻找一个正则表达式,如果“owner=”包含一个特定的所有者,比如“own2”,则该正则表达式匹配。此外,此正则表达式不应与行中的其他引用相匹配。例如,行可以是:

RESULT: test=own2 slave=def owners=own1,test,own2,newown time=32 status=fail
正则表达式不应与“test”属性的own2匹配

我花了几个小时搜索,但失败了:(

我使用egrep查找正则表达式。我尝试了以下方法:

line="RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail"
echo $line | egrep "owners=*own2*"
这无法返回任何值。我不知道正则表达式有什么问题

我正在寻找能够在所有Unix版本上工作的东西,如Linux、AIX、Solaris等

编辑-现在使用示例


非常感谢您的回复

让我用更清楚的例子来解释:

myfile的内容:

blabla  
blaaaaaa some text  
RESULT: test=abcgrp1 slave=def owners=test,own2,newown time=32 status=fail  

some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass  

some text here  
RESULT: test=abc2 slave=def owners=gr,grp1 time=32 status=pass  
我想获得状态为“通过”且“所有者”为“grp1”或“grp2”的测试
因此,最初,我写道:

grep RESULT myfile | grep "pass" | egrep "grp1|gpr2"  
没花多少时间就意识到这是不正确的,因为它在“myfile”中的第一行“RESULT”返回true

所以,我想这样写:

grep RESULT myfile | grep "pass" | egrep "owners=grp1|owners=gpr2"  
显然,对于“myfile”中的第三行“RESULT”,这将失败

因此,我需要一个正则表达式,它只在模式出现在“所有者”列表中的任何位置时匹配

注意:“所有者”列表如果有多个所有者,则以逗号分隔。否则,它只有一个值。例如:owners=abc

希望我的问题现在更清楚。

给定文件

$ cat file
RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail
此grep表达式仅显示
所有者=
之后的内容:

$ grep -Po '(?<=owners=)\w+' file
own1
测试:

$if[[”$(grep-Po'(?您是否尝试过:

echo "RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail" | grep "owners=[^ ]*own2"
例如:

$ echo "RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail" | grep -Po "owners=\K[^ ]*own[0-9]"
own1,test,own2
你也许想说:

echo $line | egrep "owners=.*own2.*"
(注意模式中额外的
s)

您可以使用:

echo "$line" | grep -E '\<owners=([[:alnum:]]+,)*own2($|[, ])'
echo“$line”| grep-E'\Pure bash解决方案:
现在,要查看是否确实存在
own2
,您可以使用
=~

if [[ ${allValues[owners]} =~ own2 ]]; then
或使用globs:

if [[ ${allValues[owners]} = *own2* ]]; then
编辑: 哎呀

想象这样的数据:
owners=own1,test,thisown2swrong,newown

前面的两个解决方案都将返回
true
,这可能不是您想要的结果。
下面是一个更好的regexp:

if [[ ${allValues[owners]} =~ (^|,)own2(,|$) ]]; then

给你。这个脚本需要GNUawk(gawk)

运行
gawk-f script.awk sample.txt
将给出:

--------------------
some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass  
--------------------
--------------------
some text here  
RESULT: test=abc2 slave=def owners=gr,grp1 time=32 status=pass  
--------------------
--------------------
some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass
--------------------

代码应该可以根据您自己的要求轻松定制。如果需要帮助,请咨询我。

非常感谢您的见解和回答

结果如下:

grep RESULT myfile | grep "pass" | egrep \(\(owners=\)*\(grp1\)\|\(owners=\)*\(grp2\)\)
从这里我了解到的是

1) 如果有多个图案,请将它们括在括号中

2) 如果有多个这样的模式,它们应该用管道隔开,并且应该有另一个括号覆盖所有模式


如果只有一个这样的模式,则括号是可选的。这在我测试的所有平台上都有效,即AIX、HPUX、LINUX、SOLARIS和NT。

据我所知,OP希望检查所有者值是否包含一些字符串。而不是提取值shi@Kent。是的,我用正确的答案更新:)希望现在更清楚。你似乎对正则表达式和文件名通配符之间的区别感到困惑。即使你使用了正则表达式
*own2.*
,这个正则表达式可能适用于给定的示例。但它不可靠。如果有user
own21、own22、own222、fooown2…
我想你明白我的意思了。如果你愿意的话与大多数Shell兼容我不认为这应该被标记为
bash
。此外,根据您对文本的处理方式,我认为如果您使用Awk会更好。如果您提供更多详细信息,例如,您如何使用命令获取行,以及您计划如何处理在这些行上找到的键/值,我们可以提供更多帮助nes.@konsolebox谢谢,在帖子中添加了更多的细节!这将匹配
owners=fred,barney status=小丑24
。呃,我认为已经处理好了(参见前两个示例)无论如何,你仍然在点击
owners=小丑24
。在这些答案中,这是最接近理智的解决方案,但它需要锚定和正确的引用。
echo“$line”
用双引号,
egrep'\n你想要
egrep”owners=([:alnum:*,)*own2(,[:alnum:*)*"
@tripleee如果您认为答案很接近,但包含一些错误,您可以随时编辑其他人的答案,谢谢您升级解决方案,但我还是将您的回答视为继续进行的邀请。显然,如果出现沟通错误,请随时回滚。@tripleee哦,我不知道,谢谢。再次感谢您升级了我的answar。
if [[ ${allValues[owners]} =~ own2 ]]; then
if [[ ${allValues[owners]} = *own2* ]]; then
if [[ ${allValues[owners]} =~ (^|,)own2(,|$) ]]; then
#!/usr/bin/gawk -f

function parse_file(file,  a, count, id, key, text, values) {
    FS = " "
    id = 0
    while ((getline < file) > 0) {
        if (!/^[[:blank:]]*$/) {
            text = ""
            do {
                if (/^RESULT: /) {
                    tests[id] = text
                    tests_results[id] = $0
                    count = split($0, props)
                    for (i = 2; i <= count; ++i) {
                        match(props[i], /([^=]+)=?(.*)/, a)
                        key = a[1]; values = a[2]
                        if (length(tests_props[id])) {
                            tests_props[id] = tests_props[id] "|" key
                        } else {
                            tests_props[id] = key
                        }
                        tests_props[id "|" key] = values
                    }
                    break
                } else {
                    if (length(text)) {
                        text = text "\n" $0
                    } else {
                        text = $0
                    }
                }
            } while ((getline < file) > 0)
            ++id
        }
    }
    tests_count = id
}

function get_values(id, key, var,  a, i, t, v) {
    v = tests_props[id "|" key]
    split(v, a, /,/)
    delete var
    for (i = 1; i in a; ++i) {
        t = a[i]
        var[t] = t
    }
}

function print_test(id) {
    print "--------------------"
    print tests[id]
    print tests_results[id]
    print "--------------------"

}

BEGIN {
    parse_file(ARGV[1])
    for (i in tests) {
        get_values(i, "owners", owners)
        get_values(i, "status", status)
        if (("grp1" in owners || "grp2" in owners) && "pass" in status) {
            print_test(i)
        }
    }
    exit
}
blabla  
blaaaaaa some text  
RESULT: test=abcgrp1 slave=def owners=test,own2,newown time=32 status=fail  

some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass  

some text here  
RESULT: test=abc2 slave=def owners=gr,grp1 time=32 status=pass  

some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass
--------------------
some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass  
--------------------
--------------------
some text here  
RESULT: test=abc2 slave=def owners=gr,grp1 time=32 status=pass  
--------------------
--------------------
some more blabla  
xyze  
RESULT: test=abc1 slave=def owners=grp1,test time=32 status=pass
--------------------
grep RESULT myfile | grep "pass" | egrep \(\(owners=\)*\(grp1\)\|\(owners=\)*\(grp2\)\)