用该文件的内容替换 JSON 文档中的文件名

Kar*_*fes 0 text-processing json

我的目标:通过其内容的JSON文件的命令替换文件名sedawk或其他...

一个例子:

我的问题: 我试过sed

sed -E "s/\{\{<([^>]+)>\}\}/{r \1}/" file.json > result.json
Run Code Online (Sandbox Code Playgroud)

但是文件没有被读取,我有这个结果:

...
  "value": "{r test/myData.txt}"
...
Run Code Online (Sandbox Code Playgroud)

解决我的问题的想法sed(或更好的想法)?


解决方案:

非常感谢 !所有的答案都很有帮助,但我想使用命令而不在 GitHub 操作的默认环境中安装任何新工具。所以我在 sed 和 jq 之间进行了选择,因为它们是默认安装的。sed 不包括 json 文档中原始字符串的自动转换,所以逻辑上我更喜欢使用 jq。

我使用jq play来调试 jq 脚本。

这是最终的脚本:

...
      "value": "{{<test/myData.txt>}}"
...
Run Code Online (Sandbox Code Playgroud)

您可以在 github 上找到带有此脚本的项目。

Kus*_*nda 7

这样做sed会遇到问题,因为您需要解析文档、解码存储在 JSON 文件中的路径名(它可能具有某些 JSON 编码的字符),以及对文件内容进行编码以包含到 JSON 文档中。这当然是可行sed,它只是意味着您必须在sed.

让我们使用现有的 JSON 感知工具,例如jq.

由于我们在问题中没有看到太多文件,我将假设该文件看起来像

{
  "description": "hello world example",
  "value": "{{<test/myData.txt>}}"
}
Run Code Online (Sandbox Code Playgroud)

或等价物

{"description":"hello world example","value":"{{<test/myData.txt>}}"}
Run Code Online (Sandbox Code Playgroud)

即,该value键是 JSON 文件中的顶级键之一。

我们要在这里做的是从解析出的值value是之间的关键{{<>}}并取代与对应的路径,我们只剩下了文件的全部价值。

路径名可以jq

jq -r '.value | ltrimstr("{{<") | rtrimstr(">}}")' file.json
Run Code Online (Sandbox Code Playgroud)

这将删除侧翼{{<>}}返回解码的字符串值。

我们可以将这个字符串放入一个 shell 变量中,如下所示:

datafile=$( jq -r '.value | ltrimstr("{{<") | rtrimstr(">}}")' file.json )
Run Code Online (Sandbox Code Playgroud)

或者我们可以jq创建一个赋值语句,在 shell 中进行评估(这将允许路径名以换行符结尾),

eval "$( jq -r '.value | ltrimstr("{{<") | rtrimstr(">}}") | @sh "datafile=\(.)"' file.json )"
Run Code Online (Sandbox Code Playgroud)

@sh操作可确保我们从JSON文件解析值被安全地引用了壳。对于我的示例 JSON 文档,这将eval是字符串datafile='test/myData.txt'.

然后只需获取文件的数据并更新原始文件中该键的值即可:

jq --arg data "$(cat "$datafile")" '.value |= $data' file.json
Run Code Online (Sandbox Code Playgroud)

这将创建一个包含文件的 JSON 编码数据的jq变量$data。数据用于更新value键的值。

结果,给定我的小示例文件和您的test/myData.txt示例文件:

jq --arg data "$(cat "$datafile")" '.value |= $data' file.json
Run Code Online (Sandbox Code Playgroud)

如果您愿意,然后重定向到新的文件名。

概括:

{
  "description": "hello world example",
  "value": "blabla\nblabla"
}
Run Code Online (Sandbox Code Playgroud)

添加健全性检查和诊断消息以供品尝:

datafile=$( jq -r '.value | ltrimstr("{{<") | rtrimstr(">}}")' file.json )
jq --arg data "$(cat "$datafile")" '.value |= $data' file.json >result.json
Run Code Online (Sandbox Code Playgroud)