표적
텍스트를 "scripts: {"
다음 문자열로 바꾸십시오.
"scripts": {
"watch": "tsc -w",
파일 에서 json
.
노력하다
소스 문자열과 대상 문자열에 대해 두 개의 변수를 만들었습니다.
첫 시도
SRC='"scripts": {'
DST='"scripts": {
"watch": "tsc -w",'
그리고 다음 명령을 실행하세요:
sed "s/$SRC/$DST/" foo.json
이것은 실패했습니다.
두 번째 시도
이번에는 소스 및 대상 문자열에 대해 큰따옴표를 이스케이프 처리했습니다.
SRC="\"scripts\": {"
DST="\"scripts\": {
\"watch\": \"tsc -w\",
\"dev\": \"nodemon dist/index.js\","
위와 동일한 명령을 실행했지만 실패했습니다.
세 번째와 네 번째 시도
다음을 사용하여 위에 정의된 변수를 시도했습니다.
sed 's/'"$SRC"'/'"$DST"'/' foo.json
이것은 실패했습니다.
이러한 모든 시도에서 오류가 발생했습니다.
unterminated 's' command
무엇이 잘못되었나요?
답변1
JSON 문서가 다음과 같다고 가정해 보겠습니다.
{
"scripts": {
"other-key": "some value"
}
}
...이 객체에 다른 키-값 쌍을 삽입하려고 합니다 .scripts
. 그런 다음 다음을 사용할 수 있습니다 jq
.
$ jq '.scripts.watch |= "tsc -w"' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w"
}
}
또는,
$ jq '.scripts += { watch: "tsc -w" }' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w"
}
}
둘 다 할 것이다바꾸다이미 존재하는 .scripts.watch
항목입니다.
키-값 쌍의 순서는 .scripts
중요하지 않습니다(배열이 아니기 때문에).
출력을 저장하려면 새 파일로 리디렉션하세요.
동일한 객체에 여러 키-값 쌍을 추가합니다.
$ jq '.scripts += { watch: "tsc -w", dev: "nodemon dist/index.js" }' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w",
"dev": "nodemon dist/index.js"
}
}
jo
객체에 추가해야 하는 JSON을 생성하기 위해 결합되었습니다 .scripts
.
$ jq --argjson new "$( jo watch='tsc -w' dev='nodemon dist/index.js' )" '.scripts += $new' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w",
"dev": "nodemon dist/index.js"
}
}
sed
줄 중심 텍스트를 구문 분석하는 데 적합합니다. JSON에는 줄 바꿈으로 구분된 레코드가 포함되어 있지 않으며 sed
JSON의 인용 및 문자 인코딩 규칙을 이해하지 못합니다. 이러한 구조화된 데이터 세트(또는 XML, YAML 또는 경우에 따라 CSV)를 올바르게 구문 분석하고 수정하려면 적절한 구문 분석기를 사용해야 합니다.
이 예제를 사용하면 추가 보너스로 jq
다음과 같은 코드를 얻을 수 있습니다.용이하게필요에 맞게 수정하고 입력 데이터 구조에 대한 변경을 지원하도록 쉽게 수정할 수도 있습니다.
답변2
Kosalonanda는 절대적으로 옳습니다전용 파서가 작업에 적합한 도구라고 말합니다. 그러나 이것은 sed
(적어도 GNU를 이해하는 경우 ) 쉽게 수행할 수 있습니다 sed
. \n
두 줄 패턴 전체를 바꾸려고 하면 상황이 더 복잡해집니다. 대신, 그냥성냥문자열을 대상으로 하고 그 뒤에 대체 내용을 삽입합니다.
"scripts": {
그런 다음:
$ sed '/"scripts": {/s/$/\n "watch": "tsc -w",/' file
"scripts": {
"watch": "tsc -w",
이는 "이 줄이 문자열과 일치하는 경우 "scripts": {
줄 끝을 줄 바꿈 문자( \n
)와 줄 바꿈 문자( )로 바꿉니다 "watch": "tsc -w",
. 또는 a
sed 명령을 사용하여 텍스트를 추가할 수 있습니다.
$ sed '/"scripts": {/a\ "watch": "tsc -w",' file
"scripts": {
"watch": "tsc -w",
답변3
여기서는 Sed 명령을 생성하고 여기에 개행 문자를 추가합니다.
sed "s/$SRC/$DST/" foo.json
줄 바꿈으로 명령이 종료되므로 이는 유효하지 않습니다. \n
문자 그대로의 개행 문자 대신에 작성해야 합니다 . 일부 쉘(Bash, zsh 등..., 그러나 일반 POSIX 쉘은 아님)에서는 매개변수 대체를 사용하여 이를 수행할 수 있습니다.
DST=${DST//$'\n'/\\n}
# // replace every
# $'\n' newline
# / with
# \\n \ and n
다른 대체 문자열의 경우 따옴표가 필요할 수도 있습니다 /
.
DST=${DST//\//\\/}
또한 \
(이것을 먼저 수행합니다)은 &
대체 텍스트에서 특별한 의미를 가지므로 대체가 필요합니다.
답변4
sed
모든 텍스트가 고려 되므로 문자열을 코드 regex
에 삽입하기 전에 문자열을 sed
이스케이프 해야 합니다. 또한 입력한 문자열이 명령의 왼쪽에 있는지 오른쪽에 있는지 주의 깊게 살펴봐야 합니다 s///
. 양쪽의 BRE 문자 목록이 다르기 때문입니다.
s='[[:blank:]]'
srch_str='"scripts": {'
repl_str='"watch": "tsc -w",'
esc_srch_str=$(
printf '%s\n' "$srch_str" |
sed -e 's:[][\/.^$*]:\\&:g'
)
esc_repl_str=$(
printf '%s\n' "$repl_str" |
sed -e 's:[\/&]:\\&:g'
)
sed -e "
/^$s*$esc_srch_str\$/G
s/^\($s*\).*\n/&\1 $esc_repl_str/
" file
산출:
{
"scripts": {
"watch": "tsc -w",
"other-key": "some value"
}
}