使用 JQ 从不同目录获取 json 字段值
Get json field value with JQ from different directory
标题可能不正确,因为我不确定这是哪里失败了。我在一个目录中有一个 bash 脚本 运行,在另一个目录中有一个 JSON 文件,我需要一个值。我想将外部目录中的值复制到当前目录中的相同 JSON 文件中。
我正在使用 jq 获取值,但我不知道如何从脚本 运行 所在的目录以外的目录中获取值。
文件结构的相关位如下;
cloudformation
- parameters_v13.json
environment_files
- prepare_stack_files.json (the script this is run from)
- directory, changes based on where the script is pointed
- created directory where created files are being output
- GREPNAME_parameters.json
我感兴趣的 JSON 文件块如下所示;
[
{
"ParameterKey": "RTSMEMAIL",
"ParameterValue": "secretemail"
}
]
脚本需要从 cloudformation/parameters_v13.json
中获取 "secretemail" 并将其粘贴到 GREPNAME_parameters.json
文件中匹配的 RTSMEMAIL 字段中。
我一直在尝试以下操作,但没有成功 - 没有任何输出。也没有错误消息,只是空白输出。我知道 GREPNAME 路径是正确的,因为它在其他地方使用没有问题。
jq --arg email "$EMAIL" '(.[] | select(.ParameterKey == "RTSMEMAIL") | .ParameterValue) |= $email' ../cloudformation/parameters_v13.json | sponge ${GREPNAME}_parameters.json
这个 jq
过滤器应该可以帮助您获得 secretmail
字符串
jq '.[] | select(.ParameterKey=="RTSMEMAIL") | .ParameterValue' json
"secretemail"
为原始输出添加一个 -r
文件以删除值周围的引号
jq -r '.[] | select(.ParameterKey=="RTSMEMAIL") | .ParameterValue' json
secretemail
--raw-output / -r:
With this option, if the filter’s result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes. This can be useful for making jq filters talk to non-JSON-based systems.
如我所见,您正在尝试将 args
传递给 jq
过滤器,对于提取,您可以先通过在 bash
中设置变量来做一些事情
email="RTSMEMAIL"
现在将它作为
传递给过滤器
jq --arg email "$email" -r '.[] | select(.ParameterKey==$email) | .ParameterValue' json
secretemail
现在要将从 parameters_v13.json
文件中获取的字符串替换为您的 GREPNAME_parameters.json
,请执行以下步骤:-
首先将第一个文件的结果存储在一个变量中以便稍后重新使用,我使用该文件提取为 json
,这实际上将您的 parameters_v13.json
文件指向另一个路径。
replacementValue=$(jq --arg email "$email" -r '.[] | select(.ParameterKey==$email) | .ParameterValue' json)
现在 $replacementValue
将包含您要更新到另一个文件的 secretmail
。正如您之前指出的那样,GREPNAME_parameters.json
与第一个文件具有相似的语法。如下所示,
$ cat GREPNAME_parameters.json
[
{
"ParameterKey": "SOMEJUNK",
"ParameterValue": "somejunkvalue"
}
]
现在我明白您的意图是将上述文件中的 "ParameterValue"
替换为从其他文件中获取的值。为此,
jq --arg replace "$replacementValue" '.[] | .ParameterValue = $replace' GREPNAME_parameters.json
{
"ParameterKey": "SOMEJUNK",
"ParameterValue": "secretemail"
}
然后您可以将此输出写入临时文件并将其作为 GREPNAME_parameters.json
移回。希望这能回答您的问题。
@Alex -
(1) sponge
只是提供了一种无需管理临时文件即可修改文件的便捷方法。你可以这样使用它:
jq ........ input.json | sponge input.json
这里"input.json"是你要编辑的文件"in place"。如果你想避免覆盖输入文件,你不会使用 sponge
。事实上,我建议不要这样做,直到你完全确定那是你想要的。
(2) 有几种策略可以使用 jq 实现您所描述的内容。它们基本上分为两类:(a) 调用 jq 两次; (b) 调用 jq 一次。
忽略 sponge
部分:
两次使用jq的模式如下:
param=$(jq -r '.[]
| select(.ParameterKey == "RTSMEMAIL")|.ParameterValue
' cloudformation/parameters_v13.json )
jq --arg param "$param" -f edit.jq input.json
假设您有 jq 1.5,只需调用一次 jq 即可完成所有操作的模式为:
jq --argfile p cloudformation/parameters_v13.json -f manage.jq input.json
这里,edit.jq和manage.jq是包含合适的jq程序的文件。
根据我对您的要求的理解,edit.jq 可能如下所示:
(.[] | select(.ParameterKey == "RTSMEMAIL")|.ParameterValue) |= $param
而 manage.jq 可能看起来像这样:
($p[] | select(.ParameterKey == "RTSMEMAIL")|.ParameterValue) as $param
| (.[]| select(.ParameterKey == "RTSMEMAIL")|.ParameterValue) |= $param
标题可能不正确,因为我不确定这是哪里失败了。我在一个目录中有一个 bash 脚本 运行,在另一个目录中有一个 JSON 文件,我需要一个值。我想将外部目录中的值复制到当前目录中的相同 JSON 文件中。
我正在使用 jq 获取值,但我不知道如何从脚本 运行 所在的目录以外的目录中获取值。
文件结构的相关位如下;
cloudformation
- parameters_v13.json
environment_files
- prepare_stack_files.json (the script this is run from)
- directory, changes based on where the script is pointed
- created directory where created files are being output
- GREPNAME_parameters.json
我感兴趣的 JSON 文件块如下所示;
[
{
"ParameterKey": "RTSMEMAIL",
"ParameterValue": "secretemail"
}
]
脚本需要从 cloudformation/parameters_v13.json
中获取 "secretemail" 并将其粘贴到 GREPNAME_parameters.json
文件中匹配的 RTSMEMAIL 字段中。
我一直在尝试以下操作,但没有成功 - 没有任何输出。也没有错误消息,只是空白输出。我知道 GREPNAME 路径是正确的,因为它在其他地方使用没有问题。
jq --arg email "$EMAIL" '(.[] | select(.ParameterKey == "RTSMEMAIL") | .ParameterValue) |= $email' ../cloudformation/parameters_v13.json | sponge ${GREPNAME}_parameters.json
这个 jq
过滤器应该可以帮助您获得 secretmail
字符串
jq '.[] | select(.ParameterKey=="RTSMEMAIL") | .ParameterValue' json
"secretemail"
为原始输出添加一个 -r
文件以删除值周围的引号
jq -r '.[] | select(.ParameterKey=="RTSMEMAIL") | .ParameterValue' json
secretemail
--raw-output / -r:
With this option, if the filter’s result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes. This can be useful for making jq filters talk to non-JSON-based systems.
如我所见,您正在尝试将 args
传递给 jq
过滤器,对于提取,您可以先通过在 bash
email="RTSMEMAIL"
现在将它作为
传递给过滤器jq --arg email "$email" -r '.[] | select(.ParameterKey==$email) | .ParameterValue' json
secretemail
现在要将从 parameters_v13.json
文件中获取的字符串替换为您的 GREPNAME_parameters.json
,请执行以下步骤:-
首先将第一个文件的结果存储在一个变量中以便稍后重新使用,我使用该文件提取为 json
,这实际上将您的 parameters_v13.json
文件指向另一个路径。
replacementValue=$(jq --arg email "$email" -r '.[] | select(.ParameterKey==$email) | .ParameterValue' json)
现在 $replacementValue
将包含您要更新到另一个文件的 secretmail
。正如您之前指出的那样,GREPNAME_parameters.json
与第一个文件具有相似的语法。如下所示,
$ cat GREPNAME_parameters.json
[
{
"ParameterKey": "SOMEJUNK",
"ParameterValue": "somejunkvalue"
}
]
现在我明白您的意图是将上述文件中的 "ParameterValue"
替换为从其他文件中获取的值。为此,
jq --arg replace "$replacementValue" '.[] | .ParameterValue = $replace' GREPNAME_parameters.json
{
"ParameterKey": "SOMEJUNK",
"ParameterValue": "secretemail"
}
然后您可以将此输出写入临时文件并将其作为 GREPNAME_parameters.json
移回。希望这能回答您的问题。
@Alex -
(1) sponge
只是提供了一种无需管理临时文件即可修改文件的便捷方法。你可以这样使用它:
jq ........ input.json | sponge input.json
这里"input.json"是你要编辑的文件"in place"。如果你想避免覆盖输入文件,你不会使用 sponge
。事实上,我建议不要这样做,直到你完全确定那是你想要的。
(2) 有几种策略可以使用 jq 实现您所描述的内容。它们基本上分为两类:(a) 调用 jq 两次; (b) 调用 jq 一次。
忽略 sponge
部分:
两次使用jq的模式如下:
param=$(jq -r '.[] | select(.ParameterKey == "RTSMEMAIL")|.ParameterValue ' cloudformation/parameters_v13.json ) jq --arg param "$param" -f edit.jq input.json
假设您有 jq 1.5,只需调用一次 jq 即可完成所有操作的模式为:
jq --argfile p cloudformation/parameters_v13.json -f manage.jq input.json
这里,edit.jq和manage.jq是包含合适的jq程序的文件。
根据我对您的要求的理解,edit.jq 可能如下所示:
(.[] | select(.ParameterKey == "RTSMEMAIL")|.ParameterValue) |= $param
而 manage.jq 可能看起来像这样:
($p[] | select(.ParameterKey == "RTSMEMAIL")|.ParameterValue) as $param
| (.[]| select(.ParameterKey == "RTSMEMAIL")|.ParameterValue) |= $param