2

我有一个通过标准输入输入到脚本的 LDAP 查询。我想搜索特定值,可能不止一个,然后通过标准输出发送找到的值。

我的 LDAP 查询如下所示:

discover-repository-location=null, File Name=null, date-detected=Tue Jun11 12:44:14 UTC 2013, endpoint-machine-name=null, incident-id=545527, sender-ip=12.1.141.87, sender-email=WinNT://tmpdm/tmpcmp, Assigned To=null, sender-port=-null, endpoint-domain-name=null, Business Unit=null, endpoint-dos-volume-name=null, file-access-date=null, date-sent=Tue Jun 11 12:44:14 UTC 2013, endpoint-file-name=null, file-modified-by=null, Country=null, Manager Email=null, plugin-chain-id=1, discover-server=null, data-owner-name=null, Dismissal Reason=null, Last Name=null, First Name=null, Phone=null, subject=HTTP incident, Sender Email=null, UserID=null, endpoint-user-name=null, endpoint-volume-name=null, discover-name=null, discover-content-root-path=null, data-owner-email=null, file-create-date=null, endpoint-application-name=null, Employee Code=null, Region=null, Manager First Name=null, path=null, endpoint-application-path=null, Manager Last Name=null, Department=null, discover-location=null, protocol=HTTP, Resolution=null, file-owner=null, Postal Code=null, endpoint-file-path=null, Title=null, discover-extraction-date=null, Script-attribute=null, Manager Phone=null, file-created-by=null, file-owner-domain=nul

假设我想从这个查询中提取协议发件人电子邮件属性,它作为单行读入。我可以通过以下方式简单地阅读它:

while read stdin line; do
     echo $line
done

现在我可以检查这些属性是否存在,但是我无法获取键值对中的值。我正在尝试使用 bash 中的正则表达式来做到这一点。我想使用 '=' 和 ',' 作为分隔符来获取完整值,然后可能使用正则表达式来验证我是否从我的属性中获取了正确的值(作为安全检查,并用于记录目的)。

任何输入都会很有用,非常感谢。

4

3 回答 3

2

如果您不想与 awk(或朋友)混淆,您也可以在纯 bash 中执行此操作:

if [[ $query =~ protocol=\([^,]+\) ]] ; then
    protocol=${BASH_REMATCH[1]}
fi
if [[ $query =~ sender-email=\([^,]+\) ]] ; then
    sender_email=${BASH_REMATCH[1]}
fi

(假设您的整个查询都在 $query 变量中)。

另请注意,我在 sender_email 变量名称中使用了“_”而不是“-”。

巧合的是,直到昨晚我才知道 BASH_REMATCH 数组,当时我碰巧也需要它!

GNU Bash 文档中的更多信息。

于 2013-09-04T18:23:11.727 回答
1

纯 bash 解决方案:

data='discover-repository-location=null, File Name=null, date-detected=Tue Jun11 12:44:14 UTC 2013, endpoint-machine-name=null, incident-id=545527, sender-ip=12.1.141.87, sender-email=WinNT://tmpdm/tmpcmp, Assigned To=null, sender-port=-null, endpoint-domain-name=null, Business Unit=null, endpoint-dos-volume-name=null, file-access-date=null, date-sent=Tue Jun 11 12:44:14 UTC 2013, endpoint-file-name=null, file-modified-by=null, Country=null, Manager Email=null, plugin-chain-id=1, discover-server=null, data-owner-name=null, Dismissal Reason=null, Last Name=null, First Name=null, Phone=null, subject=HTTP incident, Sender Email=null, UserID=null, endpoint-user-name=null, endpoint-volume-name=null, discover-name=null, discover-content-root-path=null, data-owner-email=null, file-create-date=null, endpoint-application-name=null, Employee Code=null, Region=null, Manager First Name=null, path=null, endpoint-application-path=null, Manager Last Name=null, Department=null, discover-location=null, protocol=HTTP, Resolution=null, file-owner=null, Postal Code=null, endpoint-file-path=null, Title=null, discover-extraction-date=null, Script-attribute=null, Manager Phone=null, file-created-by=null, file-owner-domain=nul'

declare -A allValues

while read -s -d ',' line; do
    IFS='=' read key value <<< "${line}"
    allValues["$key"]=$value
done <<< "$data,"

echo "${allValues['protocol']}" # prints HTTP
echo "${allValues['sender-email']}" # prints WinNT://tmpdm/tmpcmp

这样你就可以得到你想要的任何字段。当然,如果变量中有,或字符,它会吓坏。=

于 2013-09-04T18:32:47.763 回答
0

使用 awk:

 protocol=$(awk -F'=' '$1=="protocol"{print $2}' RS='[, ]+' <<< "$STR" )
 sender_email=$(awk -F'=' '$1=="sender-email "{print $2}' RS='[, ]+' <<< "$STR")

使用 Grep:

 protocol=$(grep -oP '(?<=protocol=).*?(?=, )' <<< "$STR")
 sender_email=$(grep -oP '(?<=sender-email=).*?(?=, )' <<< "$STR")
于 2013-09-04T18:08:52.590 回答