2015-11-04 6 views
10

के माध्यम से Iterating मैं पावरहेल में नीचे JSON के माध्यम से लूप करने की कोशिश कर रहा हूँ।JSON फ़ाइल PowerShell

विशेष रूप से शीर्ष टैग (जैसे 17443, 17444) नामकरण किए बिना, क्योंकि मैं उन्हें पहले से नहीं जानता हूं, मुझे डेटा के माध्यम से लूप करने का कोई तरीका नहीं मिल रहा है।

मैं सभी रिकॉर्ड के लिए टैग 3, 4 और 5 (शीर्षक, प्रथम नाम, उपनाम) आउटपुट करना चाहता हूं।

मैं इसे कैसे पूरा करूं?

किसी भी मदद की सराहना की

{ 
    "17443":{ 
     "sid":"17443", 
     "nid":"7728", 
     "submitted":"1436175407", 
     "data":{ 
     "3":{ 
      "value":[ 
       "Mr" 
      ] 
     }, 
     "4":{ 
      "value":[ 
       "Jack" 
      ] 
     }, 
     "5":{ 
      "value":[ 
       "Cawles" 
      ] 
     } 
     }, 
     "17444":{ 
     "sid":"17444", 
     "nid":"7728", 
     "submitted":"1436891400", 
     "data":{ 
      "3":{ 
       "value":[ 
        "Miss" 
       ] 
      }, 
      "4":{ 
       "value":[ 
        "Charlotte" 
       ] 
      }, 
      "5":{ 
       "value":[ 
        "Tann" 
       ] 
      } 
     } 
     }, 
     "17445":{ 
     "sid":"17445", 
     "nid":"7728", 
     "submitted":"1437142325", 
     "data":{ 
      "3":{ 
       "value":[ 
        "Mr" 
       ] 
      }, 
      "4":{ 
       "value":[ 
        "John" 
       ] 
      }, 
      "5":{ 
       "value":[ 
        "Brokland" 
       ] 
      } 
     } 
     } 
    } 
} 

मैं नीचे दिए गए कोड के साथ डेटा का उपयोग कर सकते हैं, लेकिन 17,443, 17444 में डालने से बचना चाहते हैं, आदि

 $data = ConvertFrom-Json $json 

    foreach ($i in $data.17443) 
    { 
     foreach ($t in $i.data.3) 
     { 
      write-host $t.value 
     } 
     foreach ($t in $i.data.4) 
     { 
      write-host $t.value 
     } 
     foreach ($t in $i.data.5) 
     { 
      write-host $t.value 
     } 

    } 
+2

आप कुछ भी अपने आप की कोशिश की है या आप इंतजार कर रहे हैं क्या आप यह किसी को लागू करता है कि कर सकते हैं? – Tomalak

+0

हाँ, मैं विशेष रूप से शीर्ष टैग, जैसे foreach ($ मैं में $ data.17443) { foreach ($ i.data.3 में $ टी) { लिखने-मेजबान जोड़कर डेटा प्राप्त कर सकते हैं $ t.value } foreach ($ i.data.4 में $ टी) { लिखने-मेजबान $ t.value } foreach ($ i.data.5 में $ टी) { लिखने-मेजबान $ t.value } } – Omen9876

+0

मैंने इसके साथ अपना प्रश्न संपादित किया है, इसलिए यह अधिक उपयोगी है – Omen9876

उत्तर

10

PowerShell 3.0

PowerShell 3.0 में और ऊपर आप ConvertFrom-Json cmdlet का उपयोग कर सकते हैं एक JSON कन्वर्ट करने के लिए यह मानते हुए कि $sRawJson आपके JSON इनपुट शामिल एक PowerShell डेटा संरचना में स्ट्रिंग। दुर्भाग्यपूर्ण सुविधाजनक है, यह JSON उपभोग करने के लिए बहुत आसान है क्योंकि, क्योंकि ConvertFrom-Json आप PSCustomObjects देता है, और वे कुंजी-मान जोड़ों के रूप में पदभार पुनरावृति के लिए कड़ी मेहनत कर रहे हैं -

कि सुविधाजनक और एक ही समय में दुर्भाग्यपूर्ण है।

इस विशेष JSON में, चाबियाँ गतिशील/समय से पहले ज्ञात नहीं लगती हैं, जैसे "17443" या "17444"। इसका मतलब है कि हमें कुछ ऐसी चीज चाहिए जो PSCustomObject को एक महत्वपूर्ण-मूल्य सूची में बदल दे जो foreach समझ सके।

# helper to turn PSCustomObject into a list of key/value pairs 
function Get-ObjectMembers { 
    [CmdletBinding()] 
    Param(
     [Parameter(Mandatory=$True, ValueFromPipeline=$True)] 
     [PSCustomObject]$obj 
    ) 
    $obj | Get-Member -MemberType NoteProperty | ForEach-Object { 
     $key = $_.Name 
     [PSCustomObject]@{Key = $key; Value = $obj."$key"} 
    } 
} 

अब हम वस्तु ग्राफ पार और Title, FirstName और LastName

$json = '{"17443": {"17444": {"sid": "17444","nid": "7728","submitted": "1436891400","data": {"3": {"value": ["Miss"]},"4": {"value": ["Charlotte"]},"5": {"value": ["Tann"]}}},"17445": {"sid": "17445","nid": "7728","submitted": "1437142325","data": {"3": {"value": ["Mr"]},"4": {"value": ["John"]},"5": {"value": ["Brokland"]}}},"sid": "17443","nid": "7728","submitted": "1436175407","data": {"3": {"value": ["Mr"]},"4": {"value": ["Jack"]},"5": {"value": ["Cawles"]}}}}' 

$json | ConvertFrom-Json | Get-ObjectMembers | foreach { 
    $_.Value | Get-ObjectMembers | where Key -match "^\d+$" | foreach { 
     [PSCustomObject]@{ 
      Title = $_.value.data."3".value | select -First 1 
      FirstName = $_.Value.data."4".value | select -First 1 
      LastName = $_.Value.data."5".value | select -First 1 
     } 
    } 
} 

आउटपुट

 
Title      FirstName     LastName     
-----      ---------     --------     
Miss      Charlotte     Tann      
Mr       John      Brokland     

PowerShell 2.0/वैकल्पिक दृष्टिकोण के साथ उत्पादन वस्तुओं की एक सूची का उत्पादन कर सकते

एक वैकल्पिक दृष्टिकोण जो PowerShell 2.0 (जो उपरोक्त कुछ संरचनाओं का समर्थन नहीं करता है) के लिए भी काम करता है, इसमें शामिल होगा।नेट JavaScriptSerializer class JSON को संभालने के लिए:

Add-Type -AssemblyName System.Web.Extensions 
$JS = New-Object System.Web.Script.Serialization.JavaScriptSerializer 

अब हम एक बहुत ही इसी तरह के आपरेशन कर सकते हैं -, ऊपर के रूप में भी एक सा सरल क्योंकि JavaScriptSerializer आप नियमित रूप से Dictionaries है, जो के माध्यम से कुंजी-मान जोड़ों के रूप में पदभार पुनरावृति करने के लिए आसान कर रहे हैं देता है GetEnumerator() विधि:

$json = '{"17443": {"17444": {"sid": "17444","nid": "7728","submitted": "1436891400","data": {"3": {"value": ["Miss"]},"4": {"value": ["Charlotte"]},"5": {"value": ["Tann"]}}},"17445": {"sid": "17445","nid": "7728","submitted": "1437142325","data": {"3": {"value": ["Mr"]},"4": {"value": ["John"]},"5": {"value": ["Brokland"]}}},"sid": "17443","nid": "7728","submitted": "1436175407","data": {"3": {"value": ["Mr"]},"4": {"value": ["Jack"]},"5": {"value": ["Cawles"]}}}}' 

$data = $JS.DeserializeObject($json) 

$data.GetEnumerator() | foreach { 
    $_.Value.GetEnumerator() | where { $_.Key -match "^\d+$" } | foreach { 
     New-Object PSObject -Property @{ 
      Title = $_.Value.data."3".value | select -First 1 
      FirstName = $_.Value.data."4".value | select -First 1 
      LastName = $_.Value.data."5".value | select -First 1 
     } 
    } 
} 

उत्पादन ही है:

 
Title      FirstName     LastName     
-----      ---------     --------     
Miss      Charlotte     Tann      
Mr       John      Brokland     

आप एक फ़ाइल से पढ़ने, तोका उपयोग।

  • -Raw क्योंकि अन्यथा Get-Content रिटर्न अलग-अलग लाइनों की एक सरणी और JavaScriptSerializer.DeserializeObject कि संभाल नहीं कर सकते। हाल ही में पावरहेल संस्करणों में .NET फ़ंक्शन तर्कों के लिए प्रकार-रूपांतरण में सुधार हुआ प्रतीत होता है, इसलिए यह आपके सिस्टम पर त्रुटि नहीं हो सकता है, लेकिन यदि यह करता है (या केवल सुरक्षित होने के लिए), -Raw का उपयोग करें।
  • -Encoding क्योंकि जब आप इसे पढ़ते हैं तो टेक्स्ट फ़ाइल एन्कोडिंग निर्दिष्ट करना बुद्धिमानी है और UTF-8 JSON फ़ाइलों के लिए सबसे संभावित मान है।

यदि आपके पास 4 एमबी से बड़ी जेएसओएन फ़ाइलें हैं, तो JavaScriptSerializer.MaxJsonLength property तदनुसार सेट करें।


नोट्स

  • ConvertFrom-Json() आपको लगता है कि JSON स्ट्रिंग में डेटा को दर्शाता है एक PowerShell कस्टम वस्तु (PSCustomObject) देता है।
  • आप कर सकते हैं पाश हालांकि Get-Member -type NoteProperty
  • के साथ एक कस्टम ऑब्जेक्ट के गुणों को आप गतिशील $object."$propName" सिंटैक्स का उपयोग, वैकल्पिक रूप से $object."$(some PS expression)" एक वस्तु के गुणों का उपयोग कर सकते हैं।
  • आप अपने स्वयं के कस्टम वस्तु बना सकते हैं और New-Object PSObject -Property @{...} साथ गुण का एक समूह के साथ प्रारंभ, वैकल्पिक रूप से [PSCustomObject]@{ .. } `
+0

धन्यवाद, मुझे यही चाहिए – Omen9876

-5

यहाँ एक सरल regex आधारित समाधान है ।

$oRegex = [Regex]'(?:(?<="[345]":\{"value"\:\["))[^"]+' 
$cParts = $oRegex.Matches(($sRawJson -replace '\s')) | Select-Object -ExpandProperty "Value" 

भागों में शामिल होने से पूरा नाम पाने के लिए:

for ($i = 0; $i -lt $cParts.Count/3; $i++) { $cParts[($i * 3)..($i * 3 + 2)] -join ' ' } 
+1

आप कभी भी नियमित अभिव्यक्तियों के साथ जेएसओएन को छूना नहीं चाहते हैं। – Tomalak

+0

शायद आप के अनुसार। इसके अलावा एक जवाब को कम करना जो सटीक रूप से आउटपुट करता है जो केवल पूछा गया है वह केवल सादा विघटनकारी है। –

+1

मैं उन उत्तरों को कम करता हूं जो अनुपयोगी और मूर्ख चीजें करते हैं। चाहे वे सही चीज आउटपुट के साथ पूरी तरह से बिंदु के अलावा है। मैं जवाबों को भी कम करता हूं जो सुझाव देते हैं कि एक्सएमएल या एचटीएमएल को नियमित अभिव्यक्तियों के साथ पार्स किया जा सकता है, जो वे नहीं कर सकते - ठीक इसी कारण से JSON को नियमित अभिव्यक्तियों के साथ पार्स नहीं किया जा सकता है। – Tomalak