2016-01-25 12 views
6

मुझे चीजों को पूरा करने के लिए खोल कमांड के लिए प्राथमिकता है। मेरे पास एक बहुत बड़ी फाइल है - लगभग 2.8 जीबी और सामग्री जेएसओएन की है। सब कुछ एक पंक्ति पर है, और मुझे बताया गया कि वहां कम से कम 1.5 मिलियन रिकॉर्ड हैं।स्ट्रिंग को एक बहुत बड़ी फ़ाइल में स्ट्रिंग और प्रतिस्थापित करें

मुझे उपभोग के लिए फ़ाइल तैयार करनी होगी। प्रत्येक रिकॉर्ड अपनी लाइन पर होना चाहिए। नमूना:

{"RomanCharacters":{"Alphabet":[{"RecordId":"1",...]},{"RecordId":"2",...},{"RecordId":"3",...},{"RecordId":"4",...},{"RecordId":"5",...} }} 

या, निम्नलिखित का उपयोग करें ...

{"Accounts":{"Customer":[{"AccountHolderId":"9c585258-c94c-442b-a2f0-1ebbcc274795","Title":"Mrs","Forename":"Tina","Surname":"Wright","DateofBirth":"1988-01-01","Contact":[{"Contact_Info":"9168777943","TypeId":"Mobile Number","PrimaryFlag":"No","Index":"1","Superseded":"No" },{"Contact_Info":"9503588153","TypeId":"Home Telephone","PrimaryFlag":"Yes","Index":"2","Superseded":"Yes" },{"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"No","Index":"3","Superseded":"No" },{"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"Yes","Index":"4","Superseded":"Yes" }, {"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"No","Index":"5","Superseded":"NO" },{"Contact_Info":"15482475584","TypeId":"Mobile_Phone","PrimaryFlag":"No","Index":"6","Superseded":"No" }],"Address":[{"AddressPtr":"5","Line1":"Flat No.14","Line2":"Surya Estate","Line3":"Baner","Line4":"Pune ","Line5":"new","Addres_City":"pune","Country":"India","PostCode":"AB100KP","PrimaryFlag":"No","Superseded":"No"},{"AddressPtr":"6","Line1":"A-602","Line2":"Viva Vadegiri","Line3":"Virar","Line4":"new","Line5":"banglow","Addres_City":"Mumbai","Country":"India","PostCode":"AB10V6T","PrimaryFlag":"Yes","Superseded":"Yes"}],"Account":[{"Field_A":"6884133655531279","Field_B":"887.07","Field_C":"A Loan Product",...,"FieldY_":"2015-09-18","Field_Z":"24275627"}]},{"AccountHolderId":"92a5788f-cd8f-423d-ae5f-4eb0ceb457fd","_Title":"Dr","_Forename":"Christopher","_Surname":"Carroll","_DateofBirth":"1977-02-02","Contact":[{"Contact_Info":"9168777943","TypeId":"Mobile Number","PrimaryFlag":"No","Index":"7","Superseded":"No" },{"Contact_Info":"9503588153","TypeId":"Home Telephone","PrimaryFlag":"Yes","Index":"8","Superseded":"Yes" },{"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"No","Index":"9","Superseded":"No" },{"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"Yes","Index":"10","Superseded":"Yes" }],"Address":[{"AddressPtr":"11","Line1":"Flat No.14","Line2":"Surya Estate","Line3":"Baner","Line4":"Pune ","Line5":"new","Addres_City":"pune","Country":"India","PostCode":"AB11TXF","PrimaryFlag":"No","Superseded":"No"},{"AddressPtr":"12","Line1":"A-602","Line2":"Viva Vadegiri","Line3":"Virar","Line4":"new","Line5":"banglow","Addres_City":"Mumbai","Country":"India","PostCode":"AB11O8W","PrimaryFlag":"Yes","Superseded":"Yes"}],"Account":[{"Field_A":"4121879819185553","Field_B":"887.07","Field_C":"A Loan Product",...,"Field_X":"2015-09-18","Field_Z":"25679434"}]},{"AccountHolderId":"4aa10284-d9aa-4dc0-9652-70f01d22b19e","_Title":"Dr","_Forename":"Cheryl","_Surname":"Ortiz","_DateofBirth":"1977-03-03","Contact":[{"Contact_Info":"9168777943","TypeId":"Mobile Number","PrimaryFlag":"No","Index":"13","Superseded":"No" },{"Contact_Info":"9503588153","TypeId":"Home Telephone","PrimaryFlag":"Yes","Index":"14","Superseded":"Yes" },{"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"No","Index":"15","Superseded":"No" },{"Contact_Info":"[email protected]","TypeId":"Email Address","PrimaryFlag":"Yes","Index":"16","Superseded":"Yes" }],"Address":[{"AddressPtr":"17","Line1":"Flat No.14","Line2":"Surya Estate","Line3":"Baner","Line4":"Pune ","Line5":"new","Addres_City":"pune","Country":"India","PostCode":"AB12SQR","PrimaryFlag":"No","Superseded":"No"},{"AddressPtr":"18","Line1":"A-602","Line2":"Viva Vadegiri","Line3":"Virar","Line4":"new","Line5":"banglow","Addres_City":"Mumbai","Country":"India","PostCode":"AB12BAQ","PrimaryFlag":"Yes","Superseded":"Yes"}],"Account":[{"Field_A":"3288214945919484","Field_B":"887.07","Field_C":"A Loan Product",...,"Field_Y":"2015-09-18","Field_Z":"66264768"}]}]}} 

अंतिम परिणाम होना चाहिए:

{"RomanCharacters":{"Alphabet":[{"RecordId":"1",...]}, 
{"RecordId":"2",...}, 
{"RecordId":"3",...}, 
{"RecordId":"4",...}, 
{"RecordId":"5",...} }} 

का प्रयास किया गया कमांड:

  • sed -e 's/,{"RecordId"/}]},\n{"RecordId"/g' sample.dat
  • awk '{gsub(",{\"RecordId\"",",\n{\"RecordId\"",$0); print $0}' sample.dat

प्रयास किया आदेशों छोटे फ़ाइलों के लिए पूरी तरह से ठीक काम करता है। लेकिन यह 2.8 जीबी फ़ाइल के लिए काम नहीं करता है जिसे मुझे कुशल बनाना चाहिए। बिना कारण के 10 मिनट के बाद सेड मिडवे छोड़ देता है और कुछ भी नहीं किया जाता था। कई घंटों के बाद सेगमेंटेशन फॉल्ट (कोर डंप) कारण के साथ अजीब गलती हुई। मैंने पर्ल की खोज की कोशिश की और प्रतिस्थापित किया और "स्मृति से बाहर" कहने में त्रुटि मिली।

कोई भी मदद/विचार बहुत अच्छा होगा!

मेरी मशीन पर अतिरिक्त जानकारी:

  • से अधिक 105 जीबी डिस्क स्थान उपलब्ध।
  • 8 जीबी मेमोरी
  • 4 कोर सीपीयू
  • उबंटू 14,04
+0

हमें कुछ बेहतर नमूना डेटा की आवश्यकता है - आपके डेटा का डंप होना आवश्यक नहीं है, लेकिन समस्या का चित्रण हाथ में है। इसके अलावा - क्या आपने एक पार्सर का उपयोग करने पर विचार किया है? – Sobrique

+1

मूल समस्या, मुझे लगता है कि यह है कि उन सभी 3 औजारों को लाइन-पर-एक बार पढ़ा जाता है और इस प्रकार "एकल विशाल रेखा" से घिरा हुआ होता है। न्यूलाइन के साथ कॉमा को प्रतिस्थापित करने के लिए 'tr', '' \ 012'' 'जैसी कुछ चीज़ों के साथ पहले प्री-प्रोसेसिंग का प्रयास करें। फिर लाइन-पर-ए-टाइम टूल्स बेहतर काम करेंगे। –

+0

फिर से perl के साथ प्रयास करें लेकिन $/"," सेट करें। Sed (--unbuffered) के लिए "-u" पैरामीटर भी आज़माएं। – neuhaus

उत्तर

3

पर्ल के बारे में: इस तरह }, के लिए इनपुट लाइन विभाजक $/ सेट करके देखें:

#!/usr/bin/perl 
$/= "},"; 
while (<>){ 
    print "$_\n"; 
}' 

या, एक एक लाइनर के रूप में:

$ perl -e '$/="},";while(<>){print "$_\n"}' sample.dat 
+1

यह तेजी से काम करने के लिए साबित हुआ है। समस्या का हल ढूंढने के लिए मैंने आपकी स्क्रिप्ट को संशोधित किया है। मैं इसे जल्द ही साझा करूंगा। – dat789

+0

'-n' और '-p' झंडे को देखने के लायक हो सकता है। मुझे लगता है कि आप इसे लिख सकते हैं: 'perl -pe' BEGIN {$/= "},"} प्रिंट "\ n"; } ' – Sobrique

2

रनिंग रिकॉर्ड विभाजक, उदा } उपयोग करने का प्रयास पर्ल में:

perl -l -0175 -ne 'print $_, $/' < input 

आप केवल } युक्त लाइनों वापस गोंद की जरूरत हो सकती है।

2

यह डेटा को एक रिकॉर्ड के रूप में नहीं देखकर स्मृति समस्या से बचाता है, लेकिन प्रदर्शन के संबंध में अन्य तरीकों से दूर जा सकता है (एक समय में एक ही चरित्र को संसाधित करना)। यह भी ध्यान रखें कि यह अंतर्निहित RT चर (मौजूदा रिकॉर्ड विभाजक का मूल्य) के लिए gawk की आवश्यकता है:

$ cat j.awk 
BEGIN { RS="[[:print:]]" } 
RT == "{" { bal++} 
RT == "}" { bal-- } 
{ printf "%s", RT } 
RT == "," && bal == 2 { print "" } 
END { print "" } 

$ gawk -f j.awk j.txt 
{"RomanCharacters":{"Alphabet":[{"RecordId":"1",...]}, 
{"RecordId":"2",...}, 
{"RecordId":"3",...}, 
{"RecordId":"4",...}, 
{"RecordId":"5",...} }} 
4

आप एसईडी, awk और पर्ल के साथ अपने प्रश्न टैग किया है के बाद से, मैं क्या तुम सच में की जरूरत है कि इकट्ठा एक उपकरण के लिए एक सिफारिश है। जबकि यह ऑफ-विषय है, मुझे विश्वास है कि jq ऐसा कुछ है जिसका आप उपयोग कर सकते हैं। यह sed या awk से बेहतर होगा क्योंकि यह वास्तव में JSON समझता है। यहां जेक के साथ दिखाए गए सब कुछ को प्रोग्रामिंग के साथ पर्ल में भी किया जा सकता है।निम्नलिखित (अपने नमूने के आधार पर) की तरह

मान लिया जाये कि सामग्री:

{"RomanCharacters":{"Alphabet": [ {"RecordId":"1","data":"data"},{"RecordId":"2","data":"data"},{"RecordId":"3","data":"data"},{"RecordId":"4","data":"data"},{"RecordId":"5","data":"data"} ] }} 

आप आसानी से इस स्वरूपित कर सकती है "सुंदर बनाना" के लिए यह:

$ jq '.' < data.json 
{ 
    "RomanCharacters": { 
    "Alphabet": [ 
     { 
     "RecordId": "1", 
     "data": "data" 
     }, 
     { 
     "RecordId": "2", 
     "data": "data" 
     }, 
     { 
     "RecordId": "3", 
     "data": "data" 
     }, 
     { 
     "RecordId": "4", 
     "data": "data" 
     }, 
     { 
     "RecordId": "5", 
     "data": "data" 
     } 
    ] 
    } 
} 

और हम करने के लिए डेटा के लिए खुदाई कर सकते हैं केवल उन रिकॉर्ड्स को पुनर्प्राप्त करें जिनमें वे रुचि रखते हैं (भले ही वे क्या लिपटे हैं):

$ jq '.[][][]' < data.json 
{ 
    "RecordId": "1", 
    "data": "data" 
} 
{ 
    "RecordId": "2", 
    "data": "data" 
} 
{ 
    "RecordId": "3", 
    "data": "data" 
} 
{ 
    "RecordId": "4", 
    "data": "data" 
} 
{ 
    "RecordId": "5", 
    "data": "data" 
} 

मनुष्यों द्वारा और अजीब जैसे टूल्स द्वारा सामग्री लाइन-दर-लाइन प्रक्रिया करने के लिए बहुत अधिक पठनीय है। आप अपने प्रश्न प्रति प्रसंस्करण के लिए अपने लाइनों में शामिल करना चाहते हैं, तो awk और अधिक सरल हो जाता है:

$ jq '.[][][]' < data.json | awk '{printf("%s ",$0)} /}/{printf("\n")}' 
{ "RecordId": "1", "data": "data" } 
{ "RecordId": "2", "data": "data" } 
{ "RecordId": "3", "data": "data" } 
{ "RecordId": "4", "data": "data" } 
{ "RecordId": "5", "data": "data" } 

या, जैसा कि @peak टिप्पणी में सुझाव दिया है, पूरी तरह JQ के -c (कॉम्पैक्ट उत्पादन का उपयोग करके thie की awk भाग को खत्म) विकल्प:

$ jq -c '.[][][]' < data.json 
{"RecordId":"1","data":"data"} 
{"RecordId":"2","data":"data"} 
{"RecordId":"3","data":"data"} 
{"RecordId":"4","data":"data"} 
{"RecordId":"5","data":"data"} 
+0

ध्यान दें कि jq's -c विकल्प का लाभ यहां उपयोग करने के लिए किया जा सकता है। Data.json, 'jq -c' का उपयोग करते हुए उदाहरण में। [] [] [] ' peak

+0

@peak - शानदार, इसके लिए धन्यवाद, किसी कारण से जो कभी मेरे साथ नहीं हुआ। :-) मैंने इसे अपने उत्तर में जोड़ा है। – ghoti

0

यहाँ प्रदान की नमूना डेटा का उपयोग करना (एक है कि {खातों के साथ शुरू होता है: {ग्राहक ...), इस समस्या का समाधान एक ही है कि में पढ़ता है फ़ाइल और जैसा कि यह पढ़ रहा है यह $/में परिभाषित delimiters की संख्या गिन रहा है। 10,000 डिलीमीटरों की हर गिनती के लिए, यह एक नई फाइल को लिख देगा। और प्रत्येक डेलीमीटर के लिए, यह एक नई लाइन देता है।

#!/usr/bin/perl 

$base="/home/dat789/incoming"; 
#$_="sample.dat"; 

$/= "}]},"; # delimiter to find and insert new line after 
$n = 0; 
$match=""; 
$filecount=0; 
$recsPerFile=10000; # set number of records in a file 

print "Processing " . $_ ."\n"; 

while (<>){ 
    if ($n < $recsPerFile) { 
     $match=$match.$_."\n"; 
     $n++; 
     print "."; #This is so that we'd know it has done something 
    }  
    else { 
     my $newfile="partfile".$recsPerFile."-".$filecount . ".dat"; 
     open (OUTPUT,'>', $newfile); 
     print OUTPUT $match; 
     $match=""; 
     $filecount++; 
     $n=0; 
    print "Wrote file " . $newfile . "\n"; 
    } 
} 

print "Finished\n\n"; 

मैं बड़ा 2.8 जीबी फ़ाइल जहां यह सामग्री है एक अस्वरूपित एक लाइनर JSON है के खिलाफ इस स्क्रिप्ट का उपयोग किया है: यहां बताया स्क्रिप्ट जैसा है। परिणामी आउटपुट फाइलों में सही JSON शीर्षलेख और पाद लेख गायब होंगे लेकिन इसे आसानी से ठीक किया जा सकता है।

योगदान देने के लिए बहुत बहुत धन्यवाद!

संबंधित मुद्दे