私はシェルスクリプトが初めてです。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
編集- OPは構文の説明を求めました。 正規表現の構文は大きなトピックであり、ここではすべてを説明することはできませんが、例を理解できるように十分に説明しようと思います。
re="http://([^/]+)/"
これは、bash 変数に格納される正規表現re
です。つまり、入力文字列を一致させ、できれば部分文字列を抽出するものです。それを分解する:
http://
は単なる文字列です - 正規表現が一致するには、入力文字列にこの部分文字列が含まれている必要があります[]
通常、角括弧は「括弧内の任意の文字に一致する」という意味で使用されます。したがってc[ao]t
、"cat" と "cot" の両方に一致します。内の^
文字[]
はこれを変更して、「角括弧内の文字を除く任意の文字に一致します。したがって、この場合[^/]
、「/」以外の任意の文字に一致します。+
と、「前のサブ式の 1 つ以上に一致」となります。その[^/]+
ため、「/」を除くすべての文字のセットの 1 つ以上に一致します。()
で囲むことは、後で処理するためにその部分式に一致したものをすべて保存することを意味します。使用している言語がこれをサポートしている場合、これらのサブマッチを取得するメカニズムが提供されます。bash の場合、これは BASH_REMATCH 配列です。次に、正規表現に対して入力文字列をテストして、一致するかどうかを確認する必要があります。これを行うには、bash 条件を使用できます。
if [[ $name =~ $re ]]; then
echo ${BASH_REMATCH[1]}
fi
bash では、[[ ]]
拡張条件テストを指定し、=~
bash 正規表現演算子を含めることができます。この場合、入力文字列$name
が正規表現に一致するかどうかをテストします$re
。一致する場合、正規表現の構築により、(括弧から()
) サブマッチがあることが保証され、BASH_REMATCH 配列を使用してそれにアクセスできます。
${BASH_REMATCH[0]}
、正規表現、つまり " http://www.google.com/ " に一致する文字列全体になります。()
正規表現内に複数のサブマッチを含めることができることに注意してください。BASH_REMATCH
要素はこれらに順番に対応します。したがって、この場合${BASH_REMATCH[1]}
、「www.google.com」が含まれます。これは、必要な文字列だと思います。BASH_REMATCH 配列の内容は、正規表現=~
演算子が最後に使用されたときにのみ適用されることに注意してください。したがって、さらに正規表現の一致を行う場合は、毎回この配列から必要な内容を保存する必要があります。
これは長い説明のように思えるかもしれませんが、正規表現のいくつかの複雑さについては十分に説明しました。それらは非常に強力であり、まともなパフォーマンスが得られると思いますが、正規表現の構文は複雑です。また、正規表現の実装はさまざまであるため、言語が異なればサポートされる機能も異なり、構文が微妙に異なる場合があります。特に、正規表現内の文字のエスケープは厄介な問題になる可能性があります。特に、これらの文字が特定の言語で別の意味を持つ場合はなおさらです。
別の行に変数を設定して条件でこの変数を参照する代わりに$re
、正規表現を条件に直接入れることができることに注意してください。ただし、bash 3.2では、そのようなリテラル正規表現を引用符で囲む必要があるかどうかに関する規則が変更されました。正規表現を別の変数に入れることは、これを回避する簡単な方法です。これにより、=~
一致演算子をサポートするすべての bash バージョンで条件が期待どおりに機能します。