例如,我们假设我们有以下一行:
RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail
这里测试,奴隶,所有者,时间和状态是不同的属性。 属性的数量可以变化,即可以存在类别= xyz等其他属性,或者某些属性可能不存在。
我正在寻找一个匹配的正则表达式,如果“owners =”包含一个特定的所有者,比如说“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”行,这将失败。
所以,我需要一个正则表达式,只有当模式出现在“所有者”列表中的任何地方时才会匹配。
注意:如果“所有者”列表包含多个所有者,则会以逗号分隔。否则,它只有一个值。例如:owner = abc
希望我的问题现在更清楚了。
答案 0 :(得分:1)
给定文件
$ cat file
RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail
此grep表达式仅显示owners=
之后的内容:
$ grep -Po '(?<=owners=)\w+' file
own1
如果文件包含更多信息,则无关紧要:
$ cat file
RESULT: test=abc slave=def owners=own1,hello=3,test,own2,newown time=32 status=fail, more things
$ grep -Po '(?<=owners=)\w+' file
own1
使用此文本,您可以继续if
条件:
if [[ "$(grep -Po '(?<=owners=)\w+' file)" == *own1* ]]; then
echo "it is there"
fi
试验:
$ if [[ "$(grep -Po '(?<=owners=)\w+' file)" == *own1* ]]; then echo "it is there"; fi
it is there
答案 1 :(得分:1)
您可以使用:
echo "$line" | grep -E '\<owners=([[:alnum:]]+,)*own2($|[, ])'
这将找到包含所有者值的任何字符串,其逗号分隔值包含own2
答案 2 :(得分:1)
line='RESULT: test=abc slave=def owners=own1,test,own2,newown time=32 status=fail'
declare -A allValues
while read -r -d ' ' curValue; do
IFS='=' read key value <<< "${curValue}"
allValues["$key"]=$value
done <<< "${line#RESULT: } "
这会创建一个很好的关联数组。现在很容易获得任何价值:
echo "${allValues[slave]}" # prints 'def'
echo "${allValues[owners]}" # prints 'own1,test,own2,newown'
现在,要查看own2
是否真的存在,您可以使用=~
:
if [[ ${allValues[owners]} =~ own2 ]]; then
或使用globs:
if [[ ${allValues[owners]} = *own2* ]]; then
糟糕!
想象一下这样的数据:owners=own1,test,thisown2iswrong,newown
之前的两个解决方案都将返回true
,这可能不是您想要的
这是一个更好的正则表达式:
if [[ ${allValues[owners]} =~ (^|,)own2(,|$) ]]; then
答案 3 :(得分:0)
你有没有尝试过:
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.*"
(注意模式中的额外.
)
答案 4 :(得分:0)
你走了。这个脚本需要GNU Awk(gawk)。
#!/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
正在运行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
--------------------
代码应该可以根据自己的要求轻松定制。请问我是否需要帮助。
答案 5 :(得分:0)
非常感谢您的见解和答案。
以下结果:
grep RESULT myfile | grep "pass" | egrep \(\(owners=\)*\(grp1\)\|\(owners=\)*\(grp2\)\)
据我所知,
1)当您有多个模式时,请将它们括在括号中
2)如果有多个这样的图案,它们应该用管子分开,并且应该有另一个括号覆盖所有图案
如果只有一个这样的图案,则覆盖括号是可选的。这适用于我测试的所有平台,即AIX,HPUX,LINUX,SOLARIS和NT。