불법 JSON을 생성하는 도구에 문제가 있습니다.
일부 JSON 문자열에는 00-1f 범위의 문자가 포함되어 있습니다. 그래서 이러한 문자를 \u00xx
문자열에서 적절하게 이스케이프된 값 으로 변환하고 싶습니다 .
내가 할 수 있는 최선은:
cat test2.json | jq -aR . | sed -e 's/\\"/"/g' -e 's/^"\(.*\)"$/\1/' | jq
설명하다:
jq -aR reads the data as raw input and converts
the whole thing into a single string.
This converts all control characters into
the correct form => \u00xx
sed -e 's/^"\(.*\)"$/\1/' Removes the quotes from the beginning and end.
sed -e 's/\\"/"/g' Looks for escaped quotes and removed the quotes.
jq Just makes it pretty again at the end.
Also makes sure it is valid JSON.
몇 가지 문제를 발견했습니다(다행히 아직 나에게 영향을 미치는 문제는 없습니다).
- 문자열에 포함된 '\n'이 올바르게 처리되지 않았습니다.
- 이제 모든 이스케이프 문자를 이중 이스케이프할 수 있습니다.
- 제가 고려하지 않은 다른 사항이 있을 수도 있습니다.
일부 테스트 데이터는 다음을 통해 생성될 수 있습니다.
echo -e "{ \"data\": \"XX\001YY\"}" > test2.json
그런 다음 테스트했습니다.
cat test2.json | jq -aR . | sed -e 's/\\"/"/g' -e 's/^"\(.*\)"$/\1/' | jq
생성하다:
{
"data": "XX\u0001YY"
}
newline
문자열 내부에 있을 때 => '\n' => '\x0a' 가 올바르게 처리되지 않는다는 것을 알아차렸습니다.
답변1
Perl을 사용하여 모든 C0 컨트롤을 16진수 이스케이프로 바꿀 수 있습니다.
perl -pe 's/([\x01-\x1f])/sprintf("\\u%04x", ord($1))/eg' < test.json
이것
- 프로그램을 루프로 실행하고 마지막으로 결과를 sed 스타일로 인쇄합니다(
perl -pe
). - 01-1f 범위의 모든 바이트와 일치(
s/([\x01-\x1f])/
...g
) - 바이트의 서수 값 계산(
ord($1)
) sprintf("\\u%04x", ord($1))
/e
일치하는 바이트를 ( )의 결과 로 대체
그러면 일치하는 바이트 위치에 \u0001
, \u0002
, ... 가 삽입됩니다 .\u001f
그것~ 할 것이다모든 줄 바꿈은 동일한 방식으로 이스케이프되므로 파일에 인용되지 않은 줄 바꿈이 있으면 중단됩니다(텍스트 파일에는 적어도 하나의 종료 줄 바꿈이 있지만 이는 기계적으로 전후에 제거될 수 있습니다). 이 경우 [\x01-\x09\x0b-\x1f]
건너뛰지만 있으면 실패합니다.예따옴표 안에 실제 개행 문자가 있습니다.
파일에 인용된 개행 문자와 인용되지 않은 개행 문자가 모두 포함된 경우 이러한 컨텍스트 없는 대체는 작동하지 않습니다. 파일을 있는 그대로 받아들이는 무료 JSON 파서가 필요하므로 이스케이프해야 할 파일과 그렇지 않은 파일을 알 수 있습니다. 그 중 하나에 대해서는 잘 모르겠습니다.