我试图使用 grep 命令捕获匹配的正则表达式的开头和结尾,但我不希望捕获字符串的中间部分。
这是字符串:
href="file:///home/user/file" added="2023-09-07T21:58:58Z" modified="2023-09-07T22:27:45Z" visited="2023-09-07T21:58:58Z"
我想捕获
<bookmark href="file:///home/user/file"
,排除 added="2023-09-07T21:58:58Z" modified="2023-09-07T22:27:45Z"
并捕获 visited="2023-09-07T21:58:58Z">
为了做到这一点,我尝试了以下 grep 命令:
$ grep -oP -m 10 'href="file:///.*(?="\sadded=".*visited=").*'
这是标准输出:
href="file:///home/user/file" added="2023-09-07T21:58:58Z" modified="2023-09-07T22:27:45Z" visited="2023-09-07T21:58:58Z">
这不是我正在寻找的捕获的字符串,因为
added="2023-09-07T21:58:58Z" modified="2023-09-07T22:27:45Z"
存在
我认为前瞻表达式
(?="\sadded=".*visited=")
不会更改字符串匹配位置,这就是为什么下面的.*
捕获字符串的中间,但我不确定。
正则表达式匹配始终是要匹配的字符串的连续子字符串,因此旨在匹配单个模式的
grep
命令不适合该任务。
可以改用awk,将字段分隔符设置为
'='
,将输入输出记录分隔符设置为空格,这样就可以方便地按第一个字段过滤记录了:
awk -F'=' -vRS=' ' -vORS=' ' '$1!~/added|modified/'
你可以做类似的事情
grep -o -e '^<bookmark href="[^"]*"' -e 'visited="[^"]*"$>' file
但对于更一般的情况,
grep
似乎完全是错误的工具。
sed -n 's/^\(<bookmark href="[^"]*"\).*\(visited="[^"]*"\)$>/\1\n\2/p' file
一如既往,如果您正在处理 HTML / XML,更好的方法是使用实际的 XML 解析器。