grepが先行する「.」を無視するのはなぜですか?

grepが先行する「.」を無視するのはなぜですか?

ダウンロードしたWebページで文字列を見つけようとしますcurl。私はgrep一致する文字列を見つけるために使用します。正規表現柄。

以下は私が見つけたい文字列です。

./download/file.php?id=86753

この文字列は部分Webページのより大きな文字列は次のとおりです。

href="./download/file.php?id=86753"

私が使用するマントラgrepは次のとおりです。

grep -Eo '\.\/download\/file\.php\?id=[0-9]+' dlfile.html

しかし、見つかりました。何もないhtmlファイルから。ただしgrep、次のように変更すると、2つの一致が生成されます。これ最初のゲーム2つ目は役に立たない障害物なので、含めないでください。

grep -Eo '\/download\/file\.php\?id=[0-9]+' dlfile.html
/download/file.php?id=86753
/download/file.php?id=62517

2番目の(不要な)一致を含む文字列は次のとおりです。

href="https://web.archive.org/web/20190824162104/https://www.somewhere.com/forums/download/file.php?id=62517&sid=907ab04af81e19ad758c5bcf8ebdca32"

.問題は、文字列の先行(ドット)が認識されないようです。これは、必要な文字列と望ましくない文字列の主な違いです。

Q:これがうまくいかないのはなぜですか?何が必要ですか?


私の環境:Debian派生バージョン(Raspberry Pi)、「bullseye」バージョン

私はどちらを使用していますかgrepbash

$ grep --version
grep (GNU grep) 3.6
...
$ bash --version
GNU bash, version 5.1.4(1)-release (arm-unknown-linux-gnueabihf)

ベストアンサー1

grep -EERE(拡張正規表現)が必要です。ドットは常にリテラルにエスケープする必要があります。疑問符は ERE に有効な演算子なので、リテラルと一致させるにはエスケープする必要があります。

echo 'href="./download/file.php?id=86753"' |
    grep -Eo '\./download/file.php\?id=[0-9]+'

頼む、

grepが先行する「.」を無視するのはなぜですか?

問題は、文字列の前の.(ドット)を認識しないようです。

あなたのパターンは一致し、リテラルポイントが必要です(これは正しい\.意味です)。ただし、質問に記載されている文字列は検索しようとしているWebページには表示されません。grepこれを無視しないでください。望むより:

xmlstarlet format --html BDegguyM 2>/dev/null |
    xmlstarlet select -T -t -v '//a[@class="postlink"]/@href' -n

  https://forums.raspberrypi.com/download/file.php?id=86753
  https://web.archive.org/web/20190824162104/https://www.raspberrypi.org/forums/download/file.php?id=62517&sid=907ab04af81e19ad758c5bcf8ebdca32

私はあなたがこれらの最初のものが欲しいと仮定しているので、それを抽出してみましょう。

xmlstarlet format --html BDegguyM 2>/dev/null |
    xmlstarlet select -T -t -v '//dl[@class="file"]//a[@class="postlink"]/@href' -n

  https://forums.raspberrypi.com/download/file.php?id=86753

次から始まる/download部分だけが欲しいなら

xmlstarlet format --html BDegguyM 2>/dev/null |
    xmlstarlet select -T -t -v '//dl[@class="file"]//a[@class="postlink"]/@href' -n |
    sed -E 's!^https?://[^/]+!!'

  /download/file.php?id=86753

grep操作に適したツールの代わりに実際に使用したい場合は、同じ結果が返されます。

grep -Po 'https?://[^/]+\K/download/file.php\?id=\d+' BDegguyM

  /download/file.php?id=86753

おすすめ記事