grep -oを使用して1行に複数の一致を検索して印刷する方法は?

grep -oを使用して1行に複数の一致を検索して印刷する方法は?

私はmkdocsインスタンスを持ち、ページの内部リンクを印刷するスクリプトを書いています。 1行に複数の一致がある場合、grepは一致のみを印刷できません。

これが私が現在持っているものです:

$ grep -Eon '\[([[:alpha:]]|[[:digit:]]|[[:space:]])*\]\((\/|\.).*\)' /path/to/file.md
10:[foo](../../relative_path/foobar.md) is the path to another file, also see [bar](/absolute/path/foobar.md)

出力が次のようになります。

10:[foo](../../relative_path/foobar.md)
10:[bar](/absolute/path/foobar.md)

grepやawk、sedなどの他のコマンドでこれを行う方法はありますか?

答え1

grep -Pno "[[[:alnum:]]*]\(.*?\)" /path/to/file.md

それとももっと良いかもしれません(これは一致するかもしれません)。["foo別の単語"])

grep -Pno "\[([[:alnum:]]*[[:space:]]*)*?\]\(.*?\)"

-P=>貪欲ではないマッチングのためのPerl Regex?

または、欲しくない英数字とスペースのみが可能ですが、すべての文字方法

 grep -Pno "\[.*?\]\(.*?\)"

答え2

\[([[:alpha:]]|[[:digit:]]|[[:space:]])*\]

一致すれば[foo]大丈夫です。エラーは次のとおりです。

\((\/|\.).*\)

.*非常に貪欲なので、正規表現を含めるときは注意が必要です!これにより一致します(../../relative_path/foobar.md) is the path to another file, also see [bar](/absolute/path/foobar.md)。これを連結すると、行全体が一致します。

あなたは行かなければなりません

grep -Eon '\[([[:alnum:]]|[[:space:]])*\]\((\.|\/)[^)]*\)'

鍵は.*に置き換えることです[^)]*。閉じ括弧が表示されると、後者の正規表現は停止する必要があります。また、次の変更を適用しました。

  • [[:alpha:]]|[[:digit:]]中に折り畳むことができる[[:alnum:]]

出力:

1:[foo](../../relative_path/foobar.md)
1:[bar](/absolute/path/foobar.md)

(私のファイルの最初の行なので、そうでは1:ありません。)10:

答え3

grep -on '\[[^]]*\]([^)]*)'

あなたの場合は十分かもしれません。[...]に表示される文字を本当に制限する必要がありますか(...)

[...]内部部分が数字またはスペースでのみ構成され、内部部分が(...)a/またはaで始まるように要求するには、.次のようにします。

grep -on '\[[[:alnum:][:space:]]*\]([./][^)]*)'

とにかく、asの[^)]*代わりに行の終わりとすべてを飲み込むことに注意してください。.*).*))

ここでは-E、 の|代替演算子は必要ありません。単一の文字を一致させるには、複数の文字または文字クラス(ここでは、およびの略語)を含むことができる[set]角括弧式を使用できます。set[:alnum:][:alpha:][:digit:][:space:]

答え4

貪欲ではないgrepを使用する必要があります

追加?.*((\/|\.).*?\)

grep -Pon '\[([[:alpha:]]|[[:digit:]]|[[:space:]])*\]\((\/|\.).*?\)' /path/to/file.md

10:[foo](../../relative_path/foobar.md)
10:[bar](/absolute/path/foobar.md)
  • -P貪欲ではないサポートを得るために。正規表現はPerl構文でなければなりません。

関連情報