sed 명령에 대한 파일 이름의 공백 처리

sed 명령에 대한 파일 이름의 공백 처리

en.json, en 1.json, 3개의 파일이 있습니다 en 2.json. 모두 다음과 같은 내용을 담고 있습니다.

    {
      "ABC" : "/long_name",
      "DFG" : "/{long_name}"
    }

다음 명령을 실행하여 and ABC로 바꾸었습니다.123DFG456

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파일 과 .ab

xargs대신, 다른 구분 기호를 지정 하고 사용해야 합니다 grep. 가장 좋은 구분 기호는 NUL 문자(\0)입니다. 이렇게 하려면 -Zwith grep-0with 를 사용할 수 있습니다 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하면 저장된 원본 파일이 삭제됩니다.

관련 정보