【发布时间】:2022-01-10 10:32:05
【问题描述】:
有一百万个与 sed 相关的问题,但我找不到这个具体案例。如果事实证明我是一个糟糕的谷歌用户,我会很乐意接受纠正。
我有一个包含特殊字符和换行符的文件让我们称之为 query.kql:
Metrics
| where $__timeFilter(TimeGenerated)
| where ResourceProvider == "MICROSOFT.NETWORK"
| order by TimeGenerated asc
我还有一个 json 文件。它被称为data.json:
{
"analytics": {
"query": "{{query.kql}}",
"resource": "$GlobalDataSource",
"resultFormat": "time_series"
}
}
我想做的是将 query.kql 的内容以转义形式(换行符->\n、“->”等)插入到 data.json 中的 {{query.kql}} 占位符中
这为我提供了所需格式的 query.kql 的内容(有效):
q=$(sed -e "N;s/\n/\\\n/" -e 's|["]|\\"|g' query.kql)
#q: AzureMetrics\n| where $__timeFilter(TimeGenerated) | where ResourceProvider == \"MICROSOFT.NETWORK\"\n| order by TimeGenerated asc
我尝试过的:
# This does not work, because sed chokes on the result of the shell substitution:
sed -e "s/{{query.kql}}/$q/g" data.json
# Output: sed: -e expression #1, char 79: unterminated `s' command
# This works, but the output is wrong:
sed -e "s/{{query.kql}}/`echo $q`/g" data.json
# Output is unescaped and makes the json structure invalid:
"analytics": {
"query": "AzureMetrics
| where $__timeFilter(TimeGenerated) | where ResourceProvider == "MICROSOFT.NETWORK"
| order by TimeGenerated asc",
"resource": "$GlobalDataSource",
"resultFormat": "time_series"
},
我想要输出的是 q 插入的确切内容:
{
"analytics": {
"query": "AzureMetrics\n| where $__timeFilter(TimeGenerated) | where ResourceProvider == \"MICROSOFT.NETWORK\"\n| order by TimeGenerated asc",
"resource": "$GlobalDataSource",
"resultFormat": "time_series"
}
}
如何让 sed 保持输出中 $q 的原始内容? 我也愿意接受使用 awk、perl 或 bash 脚本中通常可用的任何东西的建议。
更新
原来我的主要问题是以正确转义的方式将文件内容读入 $q 变量。如果操作正确,则无需在第二个 sed 命令中使用echo $q。
我最终完成了这项工作:
# The first part escapes quotes and backslashes, the second part replaces the newlines by \n
query=$( sed -z 's#["\]#\\\\\\&#g;s/\n/\\\\n/g' query.kql)
# I had to do some playing around before I found a suitable separator char, but turns out ~ does the trick in this specific case.
sed -i -e "s~{{query.kql}}~$query~g" $data.json
【问题讨论】:
-
你真的需要用
\n替换换行符吗? -
,1 使用双引号即可:
q="$(sed ...)" -
.2 你不知道
`echo $q`