Regex (Solaris10 grep)正则表达式匹配不同的单词

Regex (Solaris10 grep)正则表达式匹配不同的单词,regex,grep,sh,Regex,Grep,Sh,在Solaris 10中,我无法正确使用grep。我只需要一个正则表达式,它可以匹配一个包含“苹果”或“香蕉”的句子,我已经试了一个小时,但我无法让它工作 #!/bin/sh # this is NOT bash # grep usage: grep -hblcnsviw pattern file . . . RESET='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' write() { messag

在Solaris 10中,我无法正确使用grep。我只需要一个正则表达式,它可以匹配一个包含“苹果”或“香蕉”的句子,我已经试了一个小时,但我无法让它工作

#!/bin/sh
# this is NOT bash
# grep usage: grep -hblcnsviw pattern file . . .

RESET='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'

write() {
    message=$1

    if [ `echo $message | grep -c '^Success'` -gt 0 ]
    then
        echo "${GREEN}$message${RESET}"
    elif [ `echo $message | grep -c '(apple|banana)'` -gt 0 ]          # doesn't work
    then
        echo "${YELLOW}$message${RESET}"
    elif [ `echo $message | grep -c '^.*(apple|banana).*$'` -gt 0 ]    # neither
    then
        echo "${YELLOW}$message${RESET}"
    elif [ `echo $message | grep -c '/^.*(apple|banana).*$/'` -gt 0 ]  # neither
    then
        echo "${YELLOW}$message${RESET}"
    elif [ `echo $message | grep -c '^Error'` -gt 0 ]
    then
            echo "${RED}$message${RESET}"
    fi
}

write 'Success'
write 'Error'
write 'banana'
附言:如果我还需要一个正则表达式来做其他事情,它会非常有效,只是苹果和香蕉不需要正则表达式

试着逃离管道:

grep -c 'apple\|banana'
你不需要其他东西。

试着逃离管道:

grep -c 'apple\|banana'

您不需要其他东西。

我相信您需要使用
egrep
(扩展grep),以便在bourne shell中使用正则表达式和grep。不过我有点生疏了

要进行测试,请启动bourne shell:

/bin/sh
然后键入:

$ echo banana | grep -c '(apple|banana)'
0
$ echo banana | egrep -c '(apple|banana)'
1
有意思,嗯?第一个结果是0,因为它正在查找整个字符串
”(apple | banana)
,因此脚本失败。egrep将字符串解释为正则表达式,因此返回1

更多测试:

$ echo apple | egrep -c '(apple|banana)'
1
$ echo Gabriel | egrep -c '(apple|banana)'
0

我相信您需要使用
egrep
(扩展grep),以便在BourneShell中使用正则表达式和grep。不过我有点生疏了

要进行测试,请启动bourne shell:

/bin/sh
然后键入:

$ echo banana | grep -c '(apple|banana)'
0
$ echo banana | egrep -c '(apple|banana)'
1
有意思,嗯?第一个结果是0,因为它正在查找整个字符串
”(apple | banana)
,因此脚本失败。egrep将字符串解释为正则表达式,因此返回1

更多测试:

$ echo apple | egrep -c '(apple|banana)'
1
$ echo Gabriel | egrep -c '(apple|banana)'
0

默认情况下,
grep
使用基本正则表达式(BRE)格式。您可以使用
egrep
grep-E
来告诉grep改用扩展正则表达式(ERE)

ERE按照您在问题中所做的方式识别括号内的子表达式,即
(..|…)
。但是,BRE使用
\(..\)

在中搜索“子表达式”

无论哪种选择都适用于您的测试,您只需为您的grep选项使用正确的方言即可。。或者对您的方言使用正确的grep选项


根据您的用例,您可能需要考虑使用<代码> CASE <代码>语句而不是GRP.

case "$message" in
    Success*)          colour="$GREEN" ;;
    *apple*|*banana*)  colour="$YELLOW" ;;
    *plantain*)        colour="$YELLOW" ;;
    Error*)            colour="$RED" ;;
    *)                 colour="$RED"; message="UNKNOWN" ;;
esac

printf '%s%s%s\n' "$colour" "$message" "$RESET"

注意,case语句中的模式是使用Shell模式而不是正则表达式处理的。查看的“文件名生成”部分,了解有关此表示法的简单性和限制的详细信息。

默认情况下,
grep
使用基本正则表达式(BRE)格式。您可以使用
egrep
grep-E
来告诉grep改用扩展正则表达式(ERE)

ERE按照您在问题中所做的方式识别括号内的子表达式,即
(..|…)
。但是,BRE使用
\(..\)

在中搜索“子表达式”

无论哪种选择都适用于您的测试,您只需为您的grep选项使用正确的方言即可。。或者对您的方言使用正确的grep选项


根据您的用例,您可能需要考虑使用<代码> CASE <代码>语句而不是GRP.

case "$message" in
    Success*)          colour="$GREEN" ;;
    *apple*|*banana*)  colour="$YELLOW" ;;
    *plantain*)        colour="$YELLOW" ;;
    Error*)            colour="$RED" ;;
    *)                 colour="$RED"; message="UNKNOWN" ;;
esac

printf '%s%s%s\n' "$colour" "$message" "$RESET"

注意,case语句中的模式是使用Shell模式而不是正则表达式处理的。查看的“文件名生成”部分,了解有关此表示法的简单性和局限性的详细信息。

shell是调用工具的环境,而不是操作文本的工具。通用UNIX文本操作工具是awk。因此,您应该编写一个awk脚本,而不是shell脚本,它非常简单:

$ cat tst.awk
function write(message, color) {
    if      ( message ~ /^Success/ )        { color = green }
    else if ( message ~ /^(apple|banana)/ ) { color = yellow }
    else if ( message ~ /^Error/ )          { color = red }
    print color message reset
}

BEGIN {
    reset  = "\033[0m"
    red    = "\033[0;31m"
    green  = "\033[0;32m"
    yellow = "\033[0;33m"

    write("Success")
    write("Error")
    write("banana")
}

$ awk -f tst.awk
Success
Error
banana
相信我,输出的颜色是正确的


顺便说一句,Solaris(/bin/awk)上的默认awk是旧的、损坏的awk,任何人都不应该出于任何原因使用它。在Solaris上使用/usr/xpg4/bin/awk(或者,不太有用的是nawk)。

shell是一个调用工具的环境,而不是一个处理文本的工具。通用UNIX文本操作工具是awk。因此,您应该编写一个awk脚本,而不是shell脚本,它非常简单:

$ cat tst.awk
function write(message, color) {
    if      ( message ~ /^Success/ )        { color = green }
    else if ( message ~ /^(apple|banana)/ ) { color = yellow }
    else if ( message ~ /^Error/ )          { color = red }
    print color message reset
}

BEGIN {
    reset  = "\033[0m"
    red    = "\033[0;31m"
    green  = "\033[0;32m"
    yellow = "\033[0;33m"

    write("Success")
    write("Error")
    write("banana")
}

$ awk -f tst.awk
Success
Error
banana
相信我,输出的颜色是正确的


顺便说一句,Solaris(/bin/awk)上的默认awk是旧的、损坏的awk,任何人都不应该出于任何原因使用它。在Solaris上使用/usr/xpg4/bin/awk(或者,不太有用的是nawk)。

我会尝试一下,但从管道中逃脱不是很奇怪吗?我觉得这管子需要解释一下。这是否意味着我应该避开其他正则表达式符号,如括号或括号?不,是的。有点。默认情况下,grep与BREs一起工作。如果您转义BRE元字符,它将成为文字。在某些grep(例如GNU)中,如果您转义ERE元字符,则即使grep在BRE模式下运行,也会启用其ERE属性。使用
-E
参数交替调用grep,然后它将使用ERE而不是BRE,然后您不想转义任何元字符,除非您希望它们都是文本。因此,了解BRE、ERE和grep选项,然后非常小心地选择要转义的角色。幸运的是,你的问题无论如何都不是使用grep的候选问题。我会尝试一下,但是逃避管道不是很奇怪吗?我觉得这管子需要解释一下。这是否意味着我应该避开其他正则表达式符号,如括号或括号?不,是的。有点。默认情况下,grep与BREs一起工作。如果您转义BRE元字符,它将成为文字。在某些grep(例如GNU)中,如果您转义ERE元字符,则即使grep在BRE模式下运行,也会启用其ERE属性。使用
-E
参数交替调用grep,然后它将使用ERE而不是BRE,然后您不想转义任何元字符,除非您希望它们都是文本。因此,了解BRE、ERE和grep选项,然后非常小心地选择要转义的角色。幸运的是,您的问题并不适合使用grep。假设您的
grep
版本支持它,您可能希望
如果echo“$message”| grep-q“^Success”;然后
等,而不是捕获
grep的输出
。假设您的
grep
版本支持它,您可能希望
如果echo“$message”| grep-q“^Success”;然后
等,而不是捕获