sed 패턴은 "with \" 및 \를 \\로 대체합니다(json 문자열 제외).

sed 패턴은 "with \" 및 \를 \\로 대체합니다(json 문자열 제외).

"json을 제외 \"하고 대체하는 \데 문제가 있습니다.\\"

test.txt입력 파일

"a"     "b"     
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
\uff08\u524d\u5bfe\u5fdc

나는 다음과 같은 것을 출력하고 싶다

\"a\"     \"b\"     
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
\\uff08\\u524d\\u5bfe\\u5fdc

답변1

더욱 강력해지기 위해 전체 json 구문 분석을 수행할 수 있습니다.

perl -0777 -pe '
  s@(".*?"|\\)|(\{(?:"(?:\\.|[^"])*+"|(?2)|[^"{}]++)*+\})|[^{}\\"]+@
  $1 ? $1 =~ s/["\\]/\\$&/gr : $&@gse'

어떤 입력이 같나요?

"a"     "b"     "c{d"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
{
  "1": {"x": "y"}
  "2": "}}}"
  "3": ["{\"x", "}"]
}
\uff08\u524d\u5bfe\u5fdc

주어진

\"a\"     \"b\"     \"c{d\"
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
{
  "1": {"x": "y"}
  "2": "}}}"
  "3": ["{\"x", "}"]
}
\\uff08\\u524d\\u5bfe\\u5fdc

"foo\"bar"입력에 json 개체가 포함되어 있거나 "foo\nbar"json 개체 외부에 있는 경우 수행하려는 작업을 명확히 할 수 있습니다 .

답변2

보여주신 간단한 예에서는 쉽습니다. 다음으로 시작하지 않는 줄에서 문자를 이스케이프 처리하세요 {.

$ sed -E '/^[^{]/s|(["\])|\\\1|g' file 
\"a\"     \"b\"     
{"1":"female","2":"197312","3":"359","4":"201109","5":"mail"}
\\uff08\\u524d\\u5bfe\\u5fdc

그러나 JSON이 여러 줄에 걸쳐 있을 수 있다면 상황은 더욱 복잡해집니다. 이 경우 {열기 및 닫기 횟수를 계산 }하고 해당 숫자가 동일한 경우에만(즉 JSON 문자열에 없는 경우) 대체를 적용하는 작은 스크립트를 작성할 수 있습니다. 그것은 다음과 같습니다:

perl -F'' -ne 'for (@F){$op++ if /{/; $cl++ if /}/; if($cl==$op){s|["\\]|\\$&|g;}print}' file 

{그러나 JSON 문자열 자체가 JSON 부분을 포함하거나 }나타내지 않는 경우(예: {"1":"b-{c}"}또는 기타)에도 문제가 발생합니다. 이 경우에는 다음을 사용하십시오.스티븐의 방법대신에.

답변3

$ sed 's/\(\\\|^"\|"$\|"[ \t]\)/\\\1/g' test.txt | sed 's/\([ \t]\)"/\1\\"/g'
  • \"줄 시작, 줄 끝 또는 공백/탭 앞에 또는 바꾸기 :
    's/\(\\\|^"\|"$\|"[ \t]\)/\\\1/g'
  • 또는 "공백/탭 뒤:sed 's/\([ \t]\)"/\1\\"/g'

따라서 이는 json 문자열에 공백/탭이 포함되어 있지 않고 한 줄에 있는 경우에만 작동합니다.

관련 정보