JSON'daki tüm sayıları tırnak işaretleri içine alın


11

Bazı sayısal değerler içeren JSON verileri vardır. Tüm nümerikler dizelere nasıl dönüştürülür? (tırnak işaretleri ile sarın)

Misal:

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

olmalı

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

Yanıtlar:


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

Yeni bir dosyaya yönlendirin ve ardından dosyayı orijinal dosya adına taşıyın.

Düz olmayan yapılardaki sayıların dizelere daha kapsamlı bir şekilde dönüştürülmesi için,

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

Bu, verilen belgedeki her değeri özyinelemeli olarak inceler ve sayı olanları seçer. Seçilen değerler daha sonra dizgilere dönüştürülür. Ayrıca, açıkçası, anahtarlara bakar, ancak bunlar JSON'da düz sayılar olmadığından, hiçbir anahtar seçilmezdi.

Misal:

$ 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"
  ]
}

Ayrıca alıntı nulldeğiştirmek select()için

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

3
Not değişeceği o {"a":{"b":1},"b":null}kadar{ "a": "{\"b\":1}", "b": "null" }
Stéphane Chazelas

@ StéphaneChazelas Evet, alt nesneleri dizelere dönüştürür. Ancak verilen veri yapısı alt nesneler içermez.
Kusalananda

2
Sadece alt nesneler değil, diziler, boolelar ve null(OP'nin örneğinde bunlardan hiçbiri olmamasına rağmen hala IMO'ya dikkat çekmeye değer) dahil tüm değerler .
Stéphane Chazelas

Ve bir dizim varsa bunu nasıl değiştirebilirim?
VK

@ StéphaneChazelas Sıralama. Bana alay ettiğin için teşekkürler.
Kusalananda

8

İşte jtcunix yardımcı programına dayalı kolay bir çözüm :

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 $ 

Değişiklikleri doğrudan json dosyasına uygulamak isterseniz, -fanahtarı aşağıdaki gibi kullanın :

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

Önerilen çözüm, keyfi yapılandırılmış bir jsons ile doğru şekilde çalışacaktır, örneğin:

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 değerleri belirtmek isterseniz, sadece bir yürüyüş yoluna atın -w'<>n:'
  • eğer boole değerleri belirtmek isterseniz, yürüyüş yoluna atın -w'<any>b:'

Ayrıca, ters işlem (tüm sayıları çıkart) benzer şekilde kolayca elde edilir: örneğin, file.jsontüm sayıları ayırmak için, zaten "enquoted" olarak:

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 $ 

GÜNCELLEME : jtcuygulamaların son sürümü artık şablonlar ve ad alanları. Bununla, dış kabuğun çağrılmasına gerek yoktur:

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"
}

jtckullanıcı kılavuzu: https://github.com/ldn-softdev/jtc/blob/master/User%20Guide.md


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

Alıntılanmamış ve olmayan bir şey teklif []{}:,whitespaceediyorum, bu yüzden sayıları alıntı true, falseve null.

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

Özellikle bir json numarasının özelliklerine uyan ve zaten tırnak içinde olmayan alıntılar yapar.

Bunlar JSON spesifikasyonuna göre kesin bir belirteç yapar, bu bir yaklaşım değildir.


-1

Aşağıdaki yöntemle denedim ve iyi çalıştı.

Seviye azaltmak için 2 kez denedim

Komut:

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

Çıktı:

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

@Kusalananda kodu düzeltti
Praveen Kumar BS

neden kullanıyorsunuz \{1,\},? Bir öğenin bir veya daha fazla kez görünüp görünmediğini test etmek için kullanın +. Ve bu -123, 0xab, 0o12, 0b1011, 1e23 veya 1.2e3 gibi sayılar için işe yaramaz ...
phuclv

@phuclv \{1,\}, ERE'nin BRE eşdeğeridir +. Birazsed uygulamalar , ERE'leri etkinleştirmek için \+bir uzantı veya bir -Eveya -rseçenek olarak desteklenir , ancak bu taşınabilir değildir. \?standart eşdeğeri olan taşınabilir olmayan bir başka \{0,1\}
uzantıdır

@phuclv geçerli bir JSON dosyasında sıralanmamış 0xab 0o12 0b1011 sayıları bulamazsınız.
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.