当字符串包含双引号时,Sed 无法替换

当字符串包含双引号时,Sed 无法替换

执行sed命令输出错误:

sed: -e expression #1, char 14: unterminated `s' command

我试图执行的命令文件:

#!/bin/sh

old_version='\"version\": \"0.0.0\"'

year=$(date +%y)
dayOfYear=$(date +%j)

version=$year'.'$dayOfYear'.''3434'
echo $version

filepath="/opt/vsts-agent-linux/_work/5/s/projects/tl-angular-map/package.json"

echo $filepath

replace="s/"$old_version"/"$version"/g"

echo $replace

sed -i -e $replace $filepath

问题是我通过连接构建的字符串由于其中的双引号而未正确关闭。

答案1

假设version是 JSON 文档中的顶级键,您可以将其更新为您想要使用的值,jq如下所示:

jq --arg patch 3434 \
   '.version |= (now | strftime("%y.%j.") + $patch)' file.json >newfile.json

这首先在命令行上将内部变量设置$patch为补丁发布版本。然后,它使用当前时间格式化时间戳字符串strftime(),并将 on 的值添加$patch到该字符串的末尾。然后将生成的字符串分配给versionJSON 文档顶层的键,并输出生成的文档。

例子:

$ cat file.json
{
  "key": "value",
  "version": "0.0.0",
  "foo": "bar"
}
$ jq --arg patch 3434 '.version |= (now | strftime("%y.%j.") + $patch)' file.json
{
  "key": "value",
  "version": "21.292.3434",
  "foo": "bar"
}

您需要确保旧版本是不是如果不是完全更新0.0.0,则改为使用

jq --arg patch 3434 \
    'select(.version == "0.0.0").version |= (now | strftime("%y.%j.") + $patch)' file.json >newfile.json

也就是说,用于select()确保对象仅在其version值为时才会更新0.0.0

另一种表述方式,对某些人来说可能看起来更好:

jq --arg patch 3434 \
    '(now | strftime("%y.%j.") + $patch) as $version |
    select(.version == "0.0.0").version |= $version' file.json >newfile.json

答案2

将文字引号添加到字符串中并不意味着 shell 可以理解这些引号。你想要这个(注意,在 bash 版本 4.2+ 中,printf 可用于日期格式化)

old_version='"version": "0.0.0"'

# "-1" is a magic value meaning "now"
printf -v year '%(%y)T' -1
printf -v dayOfYear '$(%j)T' -1

version="$year.$dayOfYear.3434"
echo "$version"
# or even without the temp variables:
# printf -v version '%(%y)T.%(%j)T.3434' -1 -1

filepath="/opt/vsts-agent-linux/_work/5/s/projects/tl-angular-map/package.json"
echo "$filepath"

replace="s/$old_version/$version/g"
echo "$replace"

sed -i -e "$replace" "$filepath"

但是,这会将字符串替换"version": "0.0.0"21.292.3434,从而破坏文件中的 JSON 对象。

$ cat package.json
{
  "key": "value",
  "version": "0.0.0",
  "foo": "bar"
}

$ sed "s/$old_version/$version/g" package.json
{
  "key": "value",
  21.292.3434,
  "foo": "bar"
}

您应该使用什么来操作 JSON 数据设置新值:

$ jq --arg newversion "$version" '.version = $newversion' package.json
{
  "key": "value",
  "version": "21.292.3434",
  "foo": "bar"
}

相关内容