JSON으로 모든 숫자를 따옴표로 묶습니다.


11

숫자 값이 포함 된 JSON 데이터가 있습니다. 모든 숫자를 문자열로 변환하는 방법? (따옴표로 묶습니다)

예:

{
        "id":1,
        "customer":"user",
        "plate":"BMT-216-A",
        "country":"GB",
        "amount":1000,
        "pndNumber":20000,
        "zoneNumber":4
}

되어야한다

{
        "id":"1",
        "customer":"user",
        "plate":"BMT-216-A",
        "country":"GB",
        "amount":"1000",
        "pndNumber":"20000",
        "zoneNumber":"4"
}

답변:


29
$ jq 'map_values(tostring)' file.json
{
  "id": "1",
  "customer": "user",
  "plate": "BMT-216-A",
  "country": "GB",
  "amount": "1000",
  "pndNumber": "20000",
  "zoneNumber": "4"
}

새 파일로 리디렉션 한 다음 원래 파일 이름으로 이동하십시오.

평평하지 않은 구조의 숫자를 문자열로 더 철저하게 변환하려면 다음을 고려하십시오.

jq '(..|select(type == "number")) |= tostring' file.json

이것은 주어진 문서에서 모든 값을 재귀 적으로 검사하고 숫자 인 것을 선택합니다. 선택한 값은 문자열로 변환됩니다. 엄밀히 말하면 키를 볼 수도 있지만 JSON에서는 키를 사용할 수 없으므로 키를 선택할 수 없습니다.

예:

$ jq . file.json
{
  "a": {
    "b": 1
  },
  "b": null,
  "c": [
    1,
    2,
    "hello",
    4
  ]
}
$ jq '(..|select(type == "number")) |= tostring' file.json
{
  "a": {
    "b": "1"
  },
  "b": null,
  "c": [
    "1",
    "2",
    "hello",
    "4"
  ]
}

추가로 말을 인용 null의 변경 select()

select(type == "number" or type == "null")

3
참고이 변경 있음 {"a":{"b":1},"b":null}{ "a": "{\"b\":1}", "b": "null" }
스테판 Chazelas가

@ StéphaneChazelas 예, 하위 객체를 문자열로 바꿀 것입니다. 그러나 주어진 데이터 구조에는 하위 오브젝트가 없습니다.
Kusalananda

2
하위 오브젝트뿐만 아니라 배열, 부울 및 nullOP를 포함한 모든 값 (OP의 샘플에 해당 값이없는 경우에도 IMO에 주목할 가치가 있음).
Stéphane Chazelas

배열이있는 경우 어떻게 변경합니까?
VK

@ StéphaneChazelas 분류. 나를 찌르는 것에 감사합니다.
Kusalananda

8

다음은 jtc유닉스 유틸리티를 기반으로 한 쉬운 솔루션입니다 .

bash $ jtc -w'<.*>D:' -eu echo '"{}"' \; file.json
{
   "amount": "1000",
   "country": "GB",
   "customer": "user",
   "id": "1",
   "plate": "BMT-216-A",
   "pndNumber": "20000",
   "zoneNumber": "4"
}
bash $ 

json 파일에 변경 사항을 바로 적용하려면 다음과 같이 -f스위치를 사용하십시오 .

bash $ jtc -f -w'<.*>D:' -eu echo '"{}"' \; file.json

제안 된 솔루션은 임의의 구조화 된 json과 올바르게 작동합니다.

bash $ jtc -w'<.*>D:' -eu echo '"{}"' \; file.json
{
   "amount": "1000",
   "country": "GB",
   "customer": "user",
   "id": "1",
   "plate": "BMT-216-A",
   "pndNumber": "20000",
   "sub": {
      "subvalue": "123"
   },
   "zoneNumber": "4"
}
bash $ 
  • null 값을 인용하려면 walk-path를 입력하십시오. -w'<>n:'
  • 부울 값을 인용하려면 walk-path를 입력하십시오. -w'<any>b:'

또한, 역수 (모든 숫자의 인용을 해제)는 비슷한 방식으로 쉽게 달성됩니다 file.json.

bash $ jtc -w'<^\d+$>R:' -eu echo {-} \; file.json
{
   "amount": 1000,
   "country": "GB",
   "customer": "user",
   "id": 1,
   "plate": "BMT-216-A",
   "pndNumber": 20000,
   "zoneNumber": 4
}
bash $ 

업데이트 : 최신 버전의 jtc도구는 이제 템플릿과 네임 스페이스를 사용합니다. 이를 통해 외부 쉘을 호출 할 필요가 없습니다.

bash $ jtc -w'<.*>D:' -u'<.*>D:<val>v' -T'"{val}"' file.json
{
   "amount": "1000",
   "country": "GB",
   "customer": "user",
   "id": "1",
   "plate": "BMT-216-A",
   "pndNumber": "20000",
   "zoneNumber": "4"
}

jtc사용자 안내서 : https://github.com/ldn-softdev/jtc/blob/master/User%20Guide.md


4
perl -pe 's/("(?:\\.|[^"])*")|[^\s[\]{}:,"]+/$1||qq("$&")/ge' file.json

따옴표가없고 따옴표가 아닌 []{}:,whitespace것을 인용하면 숫자 true, false및을 인용합니다 null.

perl -pe 's/("(?:\\.|[^"])*")|-?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?/$1||qq("$&")/ge'

구체적으로 json 번호의 사양과 일치하는 것을 인용하고 아직 인용 부호 안에 있지 않습니다.

JSON 사양을 기반으로 정확한 토큰 화를 수행하지만 근사치가 아닙니다.


-1

아래 방법으로 시도했지만 정상적으로 작동했습니다.

파이프 라인을 2 배로 줄이려고 시도했습니다.

명령:

sed 's/[0-9]\{1,\},\?$/"&/g' filename |
sed '/[0-9]\{1,\}$/s/[0-9]\{1,\}/&"/g'|
sed '/[0-9]\{1,\},$/s/,$/"&/g`'

산출:

 {
        "id":"1",
        "customer":"user",
        "plate":"BMT-216-A",
        "country":"GB",
        "amount":"1000",
        "pndNumber":"20000",
        "zoneNumber":"4"
}

@ Kusalananda는 코드를 수정
Praveen Kumar BS

왜 사용 \{1,\},합니까? 요소가 한 번 이상 나타나는지 테스트하려면을 사용하십시오 +. -123, 0xab, 0o12, 0b1011, 1e23 또는 1.2e3과 같은 숫자에서는 작동하지 않습니다.
phuclv

@phuclv \{1,\}는 ERE와 동일한 BRE입니다 +. 일부 sed구현은 지원 \+확장 또는로 -E또는 -rERES를 활성화하는 옵션하지만 휴대용 아니에요. \?그 표준 동등하지만 다른 비 휴대용 확장\{0,1\}
스테판 Chazelas가

@phuclv 유효한 JSON 파일에서 인용되지 않은 0xab 0o12 0b1011 숫자를 찾을 수 없습니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.