jq 파일의 텍스트를 직접 바꿉니다(예: sed -i).
나는 어떤 조건으로 업데이트가 필요한 json 파일을 가지고 있습니다.
샘플 json
{
"Actions" : [
{
"value" : "1",
"properties" : {
"name" : "abc",
"age" : "2",
"other ": "test1"
}
},
{
"value" : "2",
"properties" : {
"name" : "def",
"age" : "3",
"other" : "test2"
}
}
]
}
아래와 같이 Jq를 활용하여 값과 업데이트를 매칭하는 스크립트를 작성하고 있습니다.
cat sample.json | jq '.Actions[] | select (.properties.age == "3") .properties.other = "no-test"'
출력(단자에 인쇄)
{
"value": "1",
"properties": {
"name": "abc",
"age": "2",
"other ": "test1"
}
}
{
"value": "2",
"properties": {
"name": "def",
"age": "3",
"other": "no-test"
}
}
이 명령은 필요한 변경을 수행하지만 터미널에서 전체 json을 출력하며 파일 자체는 변경하지 않습니다.
jq가 파일을 직접 변경할 수 있는 옵션이 있는지 알려주시기 바랍니다(sed-i와 유사).
이 게시물은 sed의 "-i" 옵션과 동등한 옵션이 없는 것에 대한 질문을 다루며, 특히 다음과 같은 상황을 설명합니다.
저는 많은 파일을 가지고 있고 각각의 파일을 별도의 파일에 쓰는 것은 쉽지 않을 것입니다.
적어도 Mac, Linux 또는 유사한 환경에서 작업하는 경우에는 여러 가지 옵션이 있습니다.이들의 장단점은 http://backreference.org/2011/01/29/in-place-editing-of-files/ 에서 논의되므로 다음 세 가지 기술에 중점을 두겠습니다.
하나는 단순히 다음과 같이 "&&"을 사용하는 것입니다.
jq ... INPUT > INPUT.tmp && mv INPUT.tmp INPUT
방법은 다방법은을 입니다.sponge
GNU 파일(GNU 파일)의 )moreutils
):
jq ... INPUT | sponge INPUT
세 번째 옵션은 파일에 변경 사항이 없는 경우 업데이트하지 않는 것이 유리한 경우 유용할 수 있습니다.다음은 이러한 기능을 설명하는 스크립트입니다.
#!/bin/bash
function maybeupdate {
local f="$1"
cmp -s "$f" "$f.tmp"
if [ $? = 0 ] ; then
/bin/rm $f.tmp
else
/bin/mv "$f.tmp" "$f"
fi
}
for f
do
jq . "$f" > "$f.tmp"
maybeupdate "$f"
done
에 sponge
:
cat <<< $(jq 'QUERY' sample.json) > sample.json
두 가지 문제가 발생했습니다.
- 이 문제는 텍스트 처리의 일반적인 문제이며, 기본 리눅스 배포판에서는 해결되지 않습니다.
- jq는 이 문제를 극복하기 위해 특별한 코드를 작성하지 않았습니다.
한 가지 좋은 해결책:
- 다음을 사용하여 추가 유틸리티 설치
brew install moreutils
또는 가장 좋아하는 패키지 관리자입니다.여기에는 편리한 프로그램이 포함되어 있습니다.sponge
바로 이 목적을 위하여 - 사용하다
cat myfile | jq blahblahblah | sponge myfile
즉, jq가 완료되면 jq를 실행하여 표준을 캡처한 다음 표준 출력을 다음과 같이 기록합니다.myfile
(입력 파일).
컨텍스트를 변경하지 않고 작업 개체를 업데이트할 수 있습니다.파이프를 여기에 두면 상황이 각각의 개별적인 행동으로 바뀝니다.몇 개의 괄호를 사용하여 제어할 수 있습니다.
$ jq --arg age "3" \
'(.Actions[] | select(.properties.age == $age).properties.other) = "no-test"' sample.json
이렇게 하면 다음과 같은 결과를 얻을 수 있습니다.
{
"Actions": [
{
"value": "1",
"properties": {
"name": "abc",
"age": "2",
"other ": "test1"
}
},
{
"value": "2",
"properties": {
"name": "def",
"age": "3",
"other": "no-test"
}
}
]
}
입력 파일을 대체할 파일로 결과를 리디렉션할 수 있습니다.sed처럼 파일을 인플레이스 업데이트하지 않습니다.
사용합니다yq
고급 사용자의 경우 다음과 같습니다.-i
가 필요하며, 이 (in-place update)에 됩니다. 희망이 추가되었습니다.jq
yq -iP '.Email.Port=3030' config.json -o json
-i
현장 업데이트-P
예쁜 활자-o
출력은 json이어야 합니다.
yq --version
yq (https://github.com/mikefarah/yq/) version 4.21.1
tee 명령 사용
➜ cat config.json|jq '.Actions[] | select (.properties.age == "3") .properties.other = "no-test"'|tee config.json
{
"value": "1",
"properties": {
"name": "abc",
"age": "2",
"other ": "test1"
}
}
{
"value": "2",
"properties": {
"name": "def",
"age": "3",
"other": "no-test"
}
}
➜ cat config.json
{
"value": "1",
"properties": {
"name": "abc",
"age": "2",
"other ": "test1"
}
}
{
"value": "2",
"properties": {
"name": "def",
"age": "3",
"other": "no-test"
}
}
할당은 새 값을 할당할 수 있도록 할당이 실행된 전체 개체를 인쇄합니다.
.Actions
수정된 작업 배열의
.Actions=([.Actions[] | if .properties.age == "3" then .properties.other = "no-test" else . end])
나는 if 문을 사용했지만 우리는 당신의 코드를 사용하여 같은 일을 할 수 있습니다.
.Actions=[.Actions[] | select (.properties.age == "3").properties.other = "no-test"]
위의 명령은 전체 json을 출력합니다..Actions
편집되었습니다. jq는 가지고 있지 않습니다.sed -i
기능과 비슷하지만, 당신이 해야 할 일은 그것을 스폰지로 다시 파일로 파이프하는 것입니다.| sponge
jq '.Actions=([.Actions[] | if .properties.age == "3" then .properties.other = "no-test" else . end])' sample.json | sponge sample.json
다음과 같은 작업을 수행할 수 있습니다.
echo "$(jq '. + {"registry-mirrors": ["https://docker-mirror"]}' /etc/docker/daemon.json)" > /etc/docker/daemon.json
그래서 그것은 jq를 사용하여 하위 셸의 텍스트를 얻고 그것을 '메인' 셸의 파일로 반향시킵니다.
참고: 여기서 주요 아이디어는 다음과 같은 추가 도구 없이도 이를 달성할 수 있는 방법을 설명하는 것입니다.sponge
그 정도. 대신에.echo
예를 들어 stdout에 쓸 수 있는 모든 명령을 사용할 수 있습니다. printf '%s' "$(jq ... file)" > file
.
jq 프로젝트의 P.S 이슈는 여전히 열려 있습니다: https://github.com/stedolan/jq/issues/105
이것.bash
(계속)sh
호환) 기능jqi
모든 것을 돌볼 것입니다.
용도:jqi [-i] <filename> [jq options] <jq filter>
예:
fix-node-sass()
{
jqi -i package.json '.resolutions += {"node-sass": "6.0.1"}' \
'| .devDependencies += {"node-sass": "6.0.1"}'
}
거의sed
또는perl
,명시하다-i
원본 파일을 강제로 다시 쓰기 위한 주요 인수입니다.한다면-i
지정되지 않은 경우, "드라이 런"이 되고 출력이stdout
.
어떤 불가사의한 이유로 당신이 다음과 같은 이상한 일을 하고 싶다면,
cat in.json | jq -i - > out.json
그리고나서out.json
결과 또는 원본 내용 중 하나를 보유합니다.in.json
실수로. 즉,out.json
유효한 json이어야 합니다.
참고: 7자 미만의 출력(예:null
)는 오류로 간주되며 덮어쓰지 않습니다.원하는 경우 이 안전 기능을 비활성화할 수 있습니다.
jqi ()
{
local filename=$1;
shift;
local inplace=;
local stdin=;
if [[ $filename == "-i" ]]; then
echo "jqi: in-place editing enabled" 1>&2;
inplace=y;
filename=$1;
shift;
fi;
if [[ $filename == "-" ]]; then
echo "jqi: reading/writing from stdin/stdout" 1>&2;
if [ -n "$inplace" ]; then
stdin=y;
inplace=;
fi;
filename="/dev/stdin";
fi;
local tempname="$( mktemp --directory --suffix __jq )/$( dirname "$filename" ).$$.json";
local timestamp="${tempname%json}timestamp";
local -i error=0;
cat "$filename" > "$tempname";
touch "$timestamp";
while :; do
if jq "${*}" "$filename" > "$tempname"; then
if test "$tempname" -nt "$timestamp"; then
local ls_output=($( ls -Lon "$tempname" ));
filesize=${ls_output[3]};
if [[ $filesize -lt 7 ]]; then
echo "jqi: read only $filesize bytes, not overwriting" 1>&2;
error=1;
break;
fi;
if [ -n "$inplace" ]; then
cat "$tempname" > "$filename";
else
echo "jqi: output from dry run" 1>&2;
cat "$tempname";
fi;
error=0;
break;
else
echo "jqi: output not newer, not overwriting" 1>&2;
error=1;
break;
fi;
else
echo "jqi: jq error, not overwriting" 1>&2;
error=1;
break;
fi;
done;
if [ -n "$stdin" ] && [ $error -eq 1 ]; then
echo "jqi: output original to stdout" 1>&2;
cat "$filename";
fi;
rm "$tempname" "$timestamp";
rmdir "$( dirname "$tempname" )"
}
언급URL : https://stackoverflow.com/questions/36565295/jq-to-replace-text-directly-on-file-like-sed-i
'sourcecode' 카테고리의 다른 글
Windows 서비스를 쉽게 디버그할 수 있는 방법 (0) | 2023.05.04 |
---|---|
Postgre에서 여러 열을 삭제하는 방법SQL (0) | 2023.05.04 |
@HostBinding 및 @HostListener: 그들은 무엇을 하고 무엇을 위한 것입니까? (0) | 2023.05.04 |
MongoDB에서 배열 배열 쿼리 (0) | 2023.05.04 |
데이터 프레임에 사전 추가 (0) | 2023.05.04 |