문자열에 큰따옴표가 포함된 경우 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

문자열에 리터럴 따옴표를 추가한다고 해서 쉘이 이를 이해한다는 의미는 아닙니다. 당신은 이것을 원합니다 (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"
}

관련 정보