동적 이스케이프 변수

동적 이스케이프 변수

"name":특정 정규식 구조와 일치하도록 package.json 파일의 필드를 자동으로 설정하는 이름 도우미 스크립트를 작성 중이지만 실제로 이름을 설정하는 데 몇 가지 문제가 있습니다. 일치해야 하는 정규식은 입니다 '\@abc\/([a-z]+-{0,1})+[a-z]*$'.

지금은 기본적으로 이 작업을 수행합니다(명명 규칙을 준수하는지 실제로 확인하기 위한 몇 가지 추가 작업도 수행합니다).

pattern='\@abc\/([a-z]+-{0,1})+[a-z]*$'
if [[ ! $name =~ $pattern ]]; then 
  read -rp "New name: " newName
  sed -ri "s/(\s.\"name\"\:\s\").*/\1$newName\",/g" $1/package.json
fi

보시다시피 여기서 문제는 변수가 $newNamesed에서 명령으로 처리된다는 것입니다. 이를 위해서는 이스케이프 문자가 필요합니다(사용자가 실제로 올바른 구조에 새 이름을 썼다고 가정). 이를 수행할 수 있는 방법이 있습니까? 가능한 한 종속성이 없는 것이 가장 좋습니다.

답변1

겉으로 보기에 이 질문은 중복된 질문입니다."sed" 대체에 삽입된 문자열이 모든 메타 문자를 이스케이프하는지 확인하는 방법. 그러나 JSON은 sed줄 중심의 텍스트 조작 도구인 반면 JSON은 줄 중심이 아닌 구조화된 문서 형식입니다. 따라서 sed"특정한 방식으로 사용하고 싶다"는 부분보다는 "JSON 문서를 사용하고 싶다"는 부분을 문제로 해결하는 것이 좋습니다 .


이는 JSON과 관련이 있으므로 jq.

jq --arg newname '@abc/corrected-name' \
    'select( .name | test("^@abc/([a-z]-?)+[a-z]*$") | not ).name |= $newname' file.json

이 명령은 입력이 name최상위 키가 있는 JSON 문서로 구성되어 있다고 가정합니다. (아마도) 입력 문서를 수정하고 결과를 표준 출력에 씁니다.

간단히 말해서, 이 jq표현식은 name입력 세트에서 값이 다음과 같은 최상위 키를 가진 모든 요소를 ​​선택합니다.아니요성냥 ^@abc/([a-z]-?)+[a-z]*$. 요소를 선택하면 해당 name키 값이 의 값으로 업데이트됩니다 $newvalue.

이 방법의 장점은 표현식에 셸 변수를 삽입할 필요가 없으며 $newname내부 변수에 할당된 값이 자동으로 JSON으로 인코딩된다는 것입니다 jq(특정 방식으로 인코딩해야 하는 경우).

등의 서류를 입력하세요.

{
  "name": "@abc/abc-foo"
}

명령은 변경되지 않은 채로 유지됩니다.

{
  "name": "bumblebee"
}

될 것입니다

{
  "name": "@abc/corrected-name"
}

관련 정보