如何在 grep 过滤器中使用脚本返回的值?

如何在 grep 过滤器中使用脚本返回的值?

我在 FreeBSD 的 csh 上。我想用一个用户的域形成一行,然后使用该行来过滤 exim 邮件日志,以仅获取来自/发往该用户域的邮件。

我编写了一个脚本来从 DirectAdmin 域列表中形成一行:

#!/bin/sh
user="some-user"

    list=$(cat /usr/local/directadmin/data/users/$user/domains.list)
    domaincount=$(echo $list|wc -w)
    echo $list| tr ' ' '|'

执行此脚本将返回具有如下域的行:'domain.com'或:'domain1.com|domain2.net'

现在我想用它作为 的参数grep,但是

cat /var/log/exim/mainlog |egrep `/path/to/rowscript`

什么都不返回,而手动替换/path/to/rowscript其结果会返回我想要看到的内容。

尝试使用

grep -E "`/path/to/rowscript`", 
egrep '`/path/to/rowscript`' 
egrep `/bin/sh /path/to/rowscript`
egrep $(/path/to/rowscript)
    getting "Illegal variable name."

等等,但仍然没有运气。

顺便说一句,date反引号效果很好:

cat /var/log/exim/mainlog | grep `date +%Y-%m-%d`

我究竟做错了什么?

答案1

您的脚本不应输出单引号。当你写的时候

egrep 'foo|bar'

单引号是 shell 语法的一部分。它们保护其中的字符不被扩展。如果脚本的输出中出现单引号,它们将被视为普通字符。只需省略它们即可。

有一种更简单的方法来编写脚本:用管道符号替换换行符,并删除最后一个。

list=$(</usr/local/directadmin/data/users/$user/domains.list tr '\n' '|')
echo "${list%|}"

如果您正在寻找一组固定的字符串,则不需要这样做。相反,使用-F选项grep告诉它查找固定字符串,并-f使用 选项告诉它从文件中读取模式列表。

grep -Ff /usr/local/directadmin/data/users/bob/domains.list

请注意,如果您domain.com在该文件中包含该文件,则搜索还将返回较长字符串的匹配结果,例如otherdomain.com.因此,您可能希望使用脚本构建一个在开头和结尾都有锚点的模式,从而避免虚假匹配。我不知道exim日志有什么样的标点符号;例如,如果名称周围有空格,您需要类似的内容

#!/bin/sh
list=$(</usr/local/directadmin/data/users/$1/domains.list tr '\n' '|')
echo " (${list%|}) "

并将其称为

</var/log/exim/mainlog grep -E `/path/to/rowscript bob`

或者让脚本调用 grep:

#!/bin/sh
shift
list=$(</usr/local/directadmin/data/users/$1/domains.list tr '\n' '|')
grep -E " (${list%|}) " -- "$@"

称为

</var/log/exim/mainlog /path/to/rowscript bob

相关内容