Sed'ing 失败,同时仅将文件中第一次出现的字符串替换为复杂字符串



有一个json文件(config.json):

{
"Repo": {
"docker-node" : {
"ChangelogMsg": "### Changedn- Base container moved to BaseOS 10.9.0nn### Securityn- Includes official release of nodejs 14.15.4-1 with security fixes for [CVE-2020-8265](https://nvd.nist.gov/vuln/detail/CVE-2020-8265), [CVE-2020-1971](https://nvd.nist.gov/vuln/detail/CVE-2020-1971) and [CVE-2020-8287](https://nvd.nist.gov/vuln/detail/CVE-2020-8287)nn",
"Tag": "buster-14.15.4-2"
}
}
}

我正在尝试使用属性值更新变更日志文件:Repo.docker-node.ChangelogMsg

我使用JQuery来获取所需属性的值:

repo=docker-node
CONFIG=path/to/config.json
CHANGELOG_MSG=$(jq -r --arg repovar "$repo" '.Repo[$repovar].ChangelogMsg | strings' $CONFIG)
REL_TAG=$(jq -r --arg repovar "$repo" '.Repo[$repovar].Tag | strings' $CONFIG)
CHLOG_STR=$(printf "[$REL_TAG] - $DATEn$CHANGELOG_MSGnn## ")

并且,尝试使用以下方法更新变更日志文件:

样本CHANGELOG.md:

# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
## [buster-14.15.4-1] - 2021-01-12
### Changed
- Updated to latest nodejs version on 14.x series i.e. 14.15.4-1. This brings in new features and functionalities along with some incompatibilities. For more info, see the [release notes](https://nodejs.org/en/blog/release/v14.0.0/)

使用sed:

# Replace "## " with changelog string for only first occurance in file CHANGELOG.md
sed "1,|## |s||${CHLOG_STR}|" /path/to/CHANGELOG.md

但接收:

sed: -e expression #1, char 3: unexpected `,'
使用awk

:

awk -v var1="## " -v var2="$CHLOG_STR" '{sub(var1,var2,$0); print $0}1' /path/to/CHANGELOG.md

但上面的命令不会写入/更新文件。使用-i选项,但无法识别,所以我使用:

awk -v var1="## " -v var2="$CHLOG_STR" '{sub(var1,var2,$0); print $0}1' /path/to/CHANGELOG.md > temp.txt && mv temp.txt /path/to/CHANGELOG.md

虽然它更新了CHANGELOG。Md,但会复制每一行(如下所示)并全局替换"## "而不仅仅是第一次出现

# Change Log
# Change Log
All notable changes to this project will be documented in this file.
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

下面是预期的输出:

# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
## [buster-14.15.4-2] - 2021-01-23
### Changed
- Base container moved to BaseOS 10.9.0
### Security
- Includes official release of nodejs 14.15.4-1 with security fixes for [CVE-2020-8265](https://nvd.nist.gov/vuln/detail/CVE-2020-8265), [CVE-2020-1971](https://nvd.nist.gov/vuln/detail/CVE-2020-1971) and [CVE-2020-8287](https://nvd.nist.gov/vuln/detail/CVE-2020-8287)
## [buster-14.15.4-1] - 2021-01-12
### Changed
- Updated to latest nodejs version on 14.x series i.e. 14.15.4-1. This brings in new features and functionalities along with some incompatibilities. For more info, see the [release notes](https://nodejs.org/en/blog/release/v14.0.0/)

已经使用了所有的技巧和提示在网上可用,我正在寻找解决相同的指针。你有主意吗?

不能在sed替换字符串中放入换行符直截了当的说。我们得一个一个地逃离他们。否则sed将换行符视为命令的结束,而不是替换字符串并导致错误。那么awk将是一个更好的选择。请尝试如下:

awk -v var1="## " -v var2="$CHLOG_STR" '{ sub("^"var1, var1 var2); print }' /path/to/CHANGELOG.md

输出:

# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
## [buster-14.15.4-2] - 2021-01-23
### Changed
- Base container moved to BaseOS 10.9.0
### Security
- Includes official release of nodejs 14.15.4-1 with security fixes for [CVE-2020-8265](https://nvd.nist.gov/vuln/detail/CVE-2020-8265), [CVE-2020-1971](https://nvd.nist.gov/vuln/detail/CVE-2020-1971) and [CVE-2020-8287](https://nvd.nist.gov/vuln/detail/CVE-2020-8287)
## [buster-14.15.4-1] - 2021-01-12
### Changed
- Updated to latest nodejs version on 14.x series i.e. 14.15.4-1. This brings in new features and functionalities along with some incompatibilities. For more info, see the [release notes](https://nodejs.org/en/blog/release/v14.0.0/)

您的awk脚本中的问题是:

  • 您需要将锚^添加到正则表达式##以使其生效匹配字符串的开头。否则也会匹配###
  • 你把print $01的输出加倍。

@tshiono建议的解决方案非常接近,但不知何故,它取代了所有出现的"^## "在文件中。由于我的兴趣是只替换一次,因此以下内容对我有效:

awk -v var1="^## " -v var2="$CHLOG_STR" '!x{x=sub(var1,var2)} 1' CHANGELOG.md > temp.txt && mv temp.txt CHANGELOG.md

最新更新