en.json
, en 1.json
, 3개의 파일이 있습니다 en 2.json
. 모두 다음과 같은 내용을 담고 있습니다.
{
"ABC" : "/long_name",
"DFG" : "/{long_name}"
}
다음 명령을 실행하여 and ABC
로 바꾸었습니다.123
DFG
456
grep -El 'ABC|DFG' *.json | xargs sed -ibak -e 's#ABC#123#g' -e 's#DFG#456#g'
텍스트는 다음 오류로 대체되지만 en.json
실패 en 1.json
합니다.en 2.json
sed: en: No such file or directory
어떤 이유로 공백이 무시되고 명령에서 이를 처리하는 방법을 잘 모르겠습니다.
답변1
보고 있는 문제는 공백이 구분 기호로 처리된다는 것입니다.
간단한 예:
% echo a b | xargs ls
ls: cannot access a: No such file or directory
ls: cannot access b: No such file or directory
ls
파일 과 .a
b
xargs
대신, 다른 구분 기호를 지정 하고 사용해야 합니다 grep
. 가장 좋은 구분 기호는 NUL 문자(\0)입니다. 이렇게 하려면 -Z
with grep
및 -0
with 를 사용할 수 있습니다 xargs
.
그래서 당신의 명령은
grep -Z .... | xargs -0 ....
예를 들어:
$ ls
en 1.json en 2.json en.json
$ grep -Z -El ABC *.json | xargs -0 sed -ibak -e 's/ABC/HHH/'
$ ls
en 1.json en 1.jsonbak en 2.json en 2.jsonbak en.json en.jsonbak
3개의 파일이 수정된 것을 볼 수 있습니다("bak" 파일이 생성됨).
답변2
의심스러운 경우 루프를 사용하세요.
#!/usr/bin/env bash
while IFS= read -r file; do
sed -ibak -e 's#ABC#123#g' -e 's#DFG#456#g' "$file"
done < <(grep -El 'ABC|DFG' *.json)
위의 내용은 파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.
답변3
JSON 인식 도구를 사용하여 jq
교체를 수행할 수 있습니다.
jq '."123" = ."ABC" | ."456" = ."DFG" | del(."ABC", ."DFG")'
산출
{
"123": "/long_name",
"456": "/{long_name}"
}
이것을 세 파일 모두에 적용하고 공백이 포함된 파일 이름을 인용하는 것을 기억하세요.
for file in en.json 'en 1.json' 'en 2.json'
do
cp -p -- "$file" "$file.old"
jq '."123" = ."ABC" | ."456" = ."DFG" | del(."ABC", ."DFG")'<"$file.old" >"$file" &&
: rm -f -- "$file.old"
done
:
이전 파일을 삭제 rm
하면 저장된 원본 파일이 삭제됩니다.