我正在使用这个 sed 命令来提取密钥的 json 值,比如 MyKey..
sedPattern='s/^.*"myKey":"\([^"]*\)".*$/\1/'
对于像这样的 json 字符串,
{"myKey" : 1, "yourKey": 2}
它返回我需要的东西,
1
但是\1
上面 sed 命令中的 action 是什么意思呢?
答案1
\([^"]*\)
定义了一组字符,该组实际上是在两个大括号 () 之间找到的内容,因此需要对大括号进行\(
转义\)
\1
是第一组的内容
可以使用多组大括号对定义多个组,它们是递增编号的,并且每个组都可以引用为\n
(例如\1
,,\2
等\3
),因此得名:反向引用。
答案2
\1
\(...\)
是对第一组(即表达式中的第一个)捕获的子字符串的反向引用。如果有嵌套组,则第一个组是\(
表达式中最左侧的组。
在您的示例中,它是字符串中特定位置处的子字符串[^"]*
(可能是非双引号的空字符串)。
解析 JSON 的更好、更安全的方法是使用 JSON 感知工具,例如jq
:
jq -r '.myKey' document.json
这不仅允许您使用结构化语言提取数据,而且还确保您提取的数据可能是 JSON 编码的。
我注意到你的sed
表情一点也不从给定的 JSON 文档中提取1
,除非您将文档重写为
{"myKey":"1","yourKey":2}
该文档有两个方面的不同:
键和值之间的空格不同。这对于 JSON 解析器来说并不重要,但对于不了解 JSON 结构的基于行的工具来说却很重要。
键值的类型
myKey
现在是字符串而不是数字。这对于解析器来说很重要,具体取决于它对值的处理方式。它可能必须转换为一个值,或者它可能是预期的成为一个字符串。这取决于使用数据的应用程序。
另请注意,该文档是相等的到
{
"myKey": "1",
"yourKey": 2
}
JSON 解析器看不出两者之间有什么区别,但sed
可能能够从其中一个文档中提取某些内容,但不能从另一个文档中提取某些内容。