シェルスクリプトは初めてです。 curlを使用してhttpリクエストを送信し、正規表現を使用して文字列を抽出したい。たとえば、http応答からドメイン名を抽出するにはどうすればよいですか? (例は学習目的のみです)
#!/bin/bash
name=$(curl google.com | grep "www\..*com")
echo "domain name is"
echo $name
bash正規表現 の使用:
re="http://([^/]+)/"
if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]}; fi
Edit-OPは構文の説明を求めました。 正規表現の構文 は、ここでは完全に説明できない大きなトピックですが、例を理解するのに十分な説明を試みます。
re="http://([^/]+)/"
これは、bash変数re
に格納されている正規表現です。つまり、入力文字列に一致させるもので、できれば部分文字列を抽出します。分解する:
http://
は単なる文字列です-正規表現が一致するには、入力文字列にこの部分文字列が含まれている必要があります[]
通常、角括弧は「角括弧内の任意の文字に一致する」という意味で使用されます。したがって、c[ao]t
は「cat」と「cot」の両方に一致します。 ^
内の[]
文字は、これを修正して、「すべての文字に一致するexcept角括弧内の文字。したがって、この場合[^/]
「/」以外の任意の文字に一致します。+
を末尾に追加すると、「1つ以上の先行部分式に一致」と表示されます。したがって、[^/]+
は、「/」を除くすべての文字のセットの1つ以上に一致します。()
かっこで囲むと、その部分式に一致したものを後で処理するために保存することを意味します。使用している言語がこれをサポートしている場合、これらのサブマッチを取得するメカニズムが提供されます。 bashの場合、BASH_REMATCH配列です。次に、入力文字列を正規表現に対してテストして、一致するかどうかを確認する必要があります。これを行うには、bash条件を使用できます。
if [[ $name =~ $re ]]; then
echo ${BASH_REMATCH[1]}
fi
Bashでは、[[ ]]
は拡張条件付きテストを指定し、=~
bash正規表現演算子を含めることができます。この場合、入力文字列$name
が正規表現$re
と一致するかどうかをテストします。一致する場合、正規表現の構築により、(かっこ()
から)サブマッチがあることが保証され、BASH_REMATCH配列を使用してアクセスできます。
${BASH_REMATCH[0]}
の要素0は、正規表現、つまり「 http://www.google.com/ "」に一致する文字列全体になります。()
を使用できることに注意してください-BASH_REMATCH
要素はこれらに順番に対応します。したがって、この場合、${BASH_REMATCH[1]}
には「www.google.com」が含まれます。これは、必要な文字列だと思います。BASH_REMATCH配列の内容は、正規表現=~
演算子が最後に使用されたときにのみ適用されることに注意してください。したがって、さらに正規表現の一致を実行する場合、must必要なコンテンツを毎回この配列から保存します。
これは長い説明のように思えるかもしれませんが、正規表現の複雑さのいくつかについて本当に説明しました。それらは非常に強力である可能性があり、まともなパフォーマンスであると信じていますが、正規表現の構文は複雑です。また、正規表現の実装はさまざまであるため、異なる言語は異なる機能をサポートし、構文に微妙な違いがある場合があります。特に、正規表現内の文字のエスケープは、特にそれらの文字が特定の言語で異なる意味を持つ場合、厄介な問題になる可能性があります。
別の行で$re
変数を設定し、条件でこの変数を参照する代わりに、正規表現を条件に直接配置できることに注意してください。ただし、 bash 3.2 では、そのようなリテラル正規表現を囲む引用符が必要かどうかに関するルールが変更されました。正規表現を別の変数に入れるのは簡単な方法であるため、=~
マッチ演算子をサポートするすべてのbashバージョンで期待どおりに条件が機能します。
1つの方法はsed
を使用することです。例えば:
echo $name | sed -e 's?http://www\.??'
通常、sed
正規表現は「/」で区切られますが、「?」を使用できます。 「/」を検索しているため。別のbashトリックがあります。 @DigitalTraumaの答えは、私がそれを提案するべきであることを思い出させた。それは似ています:
echo ${name#http://www.}
(DigitalTraumaは、 "http://"を処理する必要があることを思い出させてくれました。)