2016-07-19 19 views
0

Solaris 10では、grepを正しく使用することができません。私はちょうど "リンゴ"または "バナナ"を含む文にマッチする正規表現が必要です。私は1時間試していますが、動作させることはできません。(Solaris10 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' 

P.S. :

grep -c 'apple\|banana' 

そして、あなたは他のものを必要としない:私は何かのために正規表現を必要とする場合、それは非常にうまく機能し、ちょうどリンゴやバナナ

+0

あなたのバージョンの 'grep'がそれをサポートしていると仮定すると、' echo '$ message" grep -q '^成功'; 'grep'の出力をキャプチャするのではなく、'〜 'などとなります。 – chepner

答えて

1

:egrepのは、このように、それは1

より多くのテストを返す文字列を正規表現として解釈します。 egrepまたはgrep -Eを使用して、grepに拡張正規表現(ERE)を使用させることができます。

EREは、括弧で囲まれた部分式をあなたの質問で行ったやり方、つまり(..|..)で識別します。ただし、BREは\(..\|..\)を使用します。

$ echo apple | grep -c '\(apple\|banana\)' 
1 
$ echo apple | grep -E -c '(apple|banana)' 
1 

Solaris grep man pageで "サブ表現"を検索してください。

どちらのオプションもあなたのテストでは機能しますが、grepオプションに正しい方言を使用するだけです。あなたの方言に適切なgrepオプションを使用する必要があります。


あなたのユースケースに応じて、代わりのgrepのcaseステートメントを使用して検討する必要があります。

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文のパターンがシェルパターンではなく、正規表現を使用して処理されることに注意してください。この記法の簡潔さと制限の詳細については、man shの「ファイル名の生成」セクションを確認してください。

1

のためのパイプをエスケープしてみません。

+0

私はしようとしますが、パイプを脱出するのは奇妙ではありませんか?私はパイプを解釈する必要があると思った。それはparethesisや中括弧のような他の正規表現のシンボルを逃れるべきであるということですか? –

+0

いいえはい。キンダー。 grepはデフォルトでBREと連携します。 BREメタ文字をエスケープすると、リテラルになります。いくつかのgrep(例えばGNU)では、EREメタキャラクタをエスケープすると、grepがBREモードで実行中であってもEREプロパティが有効になります。 grepに '-E'引数を指定して呼び出すと、BREの代わりにEREが使用され、メタ文字をすべてリテラルにしない限り、どのメタ文字もエスケープしたくありません。 BREとERE、そしてgrepオプションについて学び、どの文字を非常に慎重に逃げるかを選択します。幸いにもあなたの問題は、とにかくgrepを使用するための候補者ではありません。 –

+0

私のために働かなかった。とにかくありがとう –

0

bourneシェルでgrepで正規表現を使用するには、egrep(拡張grep)を使用する必要があると思います。私は少し錆びています。テスト、Bourneシェルを起動するには

/bin/sh 

次のように入力します。

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

興味深いが、えっ?​​という文字列全体を探しているので、最初の結果は0です。したがって、スクリプトは失敗します。 grepは基本正規表現(BRE)フォーマットを使用し、デフォルトでは

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

シェルは、テキストを操作するツールではなく、ツールを呼び出す環境です。汎用のUNIXテキスト操作ツールはawkです。したがって、あなたは、awkスクリプトではなく、シェルスクリプトを書くべきである、それは非常に簡単です:

$ 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 

トラスト私出力が正しく着色されています。

btw Solaris(/ bin/awk)のデフォルトawkは古いawkであり、何らかの理由で誰にも使用されるべきではありません。 Solarisでは、/ usr/xpg4/bin/awkを使用します(あまり有用でない場合もあります)。

関連する問題