用例相当简单。我有一个文本文件,名称如下eg.txt
:
'simple_example': 345, 'to_demonstrate': 232,
'regex': '不容易使用'
我正在尝试捕获密钥:
grep -oP (?<=')[a-zA-Z_0-9]+(?=':) eg.txt
它给了我错误:
-bash:意外标记“(”附近出现语法错误
转义单引号也没有帮助:
grep -oP (?<=\')[a-zA-Z_0-9]+(?=\':) eg.txt
使用扩展 grep 也没有帮助:
grep -oE (?<=')[a-zA-Z_0-9]+(?=':) eg.txt
这里发生了什么?我正在将 linux bash 与 Windows 10 WSL 结合使用。
答案1
错误消息解决的问题不是单引号,而是括号。不带引号的括号对于 shell 来说是特殊的,它们的含义取决于它们在命令行上的位置。不带引号的单引号和输入重定向运算符<
将还是一个问题,因此最好引用整个正则表达式以防止 shell 将其解释为 shell 语法:
grep -P -o "(?<=')[a-zA-Z_0-9]+(?=':)" eg.txt
由于您的表达式包含单引号,并且单引号字符串不能包含单引号,因此我使用双引号来引用整个表达式。
如果您的输入是格式良好的 JSON 文档(使用双引号键和值),那么使用 JSON 解析器从中获取顶级键会更容易,例如jq
:
$ cat file
{
"simple_example": 345,
"to_demonstrate": 232,
"regex": "is not easy to use"
}
$ jq -r 'keys[]' file
regex
simple_example
to_demonstrate
这会将顶级键提取到一个数组中(使用keys
),然后将该数组扩展为一个集合(使用[]
),然后将其解码输出(即作为“原始”字符串而不是编码的 JSON 字符串,因为-r
)。