Jak*_*ake 6 grep regular-expression markdown
我有一个 mkdocs 实例,正在编写一个脚本来打印页面中的内部链接。如果每行有多个,我无法让 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)
Run Code Online (Sandbox Code Playgroud)
我希望输出如下所示:
10:[foo](../../relative_path/foobar.md)
10:[bar](/absolute/path/foobar.md)
Run Code Online (Sandbox Code Playgroud)
有没有办法在 grep 甚至其他命令(如 awk 或 sed)中执行此操作?
grep -Pno "[[[:alnum:]]*]\(.*?\)" /path/to/file.md
Run Code Online (Sandbox Code Playgroud)
或者甚至更好(这甚至可以匹配["foo anotherword"])
grep -Pno "\[([[:alnum:]]*[[:space:]]*)*?\]\(.*?\)"
Run Code Online (Sandbox Code Playgroud)
-P => Perl Regex 用于匹配非贪婪使用 ?
或者,如果不只需要字母数字和空格,而是任何字符意味着
grep -Pno "\[.*?\]\(.*?\)"
Run Code Online (Sandbox Code Playgroud)
\[([[:alpha:]]|[[:digit:]]|[[:space:]])*\]
Run Code Online (Sandbox Code Playgroud)
会匹配[foo],那就可以了。错误在于它来了之后:
\((\/|\.).*\)
Run Code Online (Sandbox Code Playgroud)
在包含正则表达式时需要小心.*,因为它非常非常贪婪!这样就可以匹配了(../../relative_path/foobar.md) is the path to another file, also see [bar](/absolute/path/foobar.md)。连接起来,整行就已经匹配好了。
你应该去
grep -Eon '\[([[:alnum:]]|[[:space:]])*\]\((\.|\/)[^)]*\)'
Run Code Online (Sandbox Code Playgroud)
关键是替换.*为[^)]*,要求后一个正则表达式在右括号出现时停止。另外,我还应用了此更改:
[[:alpha:]]|[[:digit:]]可以折叠成[[:alnum:]]输出:
1:[foo](../../relative_path/foobar.md)
1:[bar](/absolute/path/foobar.md)
Run Code Online (Sandbox Code Playgroud)
(我有1:而不是10:因为它是我文件中的第一行。)