2010-05-06 18 views
5

मैं एक बड़ी xml फ़ाइल में टेक्स्ट का एक टुकड़ा ढूंढना चाहता हूं और किसी अन्य पाठ के साथ प्रतिस्थापित करना चाहता हूं। फ़ाइल का आकार लगभग (50 जीबी) है। मैं इसे कमांड लाइन में करना चाहता हूं। मैं पावरहेल देख रहा हूं और जानना चाहता हूं कि यह बड़े आकार को संभाल सकता है या नहीं। इसके अलावा मैं पावरहेल में प्रमुख ऑपरेटरों से बचने के लिए वाक्यविन्यास जानना चाहता हूं। मैं एक PowerShell नौसिखियाएक बड़ी फ़ाइल में खोजें और बदलें

हूँ वर्तमान में मैं कुछ इस तरह कोशिश कर रहा हूँ, लेकिन यह पसंद नहीं है यह

Get-Content C:\File1.xml | Foreach-Object {$_ -replace "xmlns:xsi=\"http:\/\/www\.w3\.org\/2001\/XMLSchema-instance\"", ""} | Set-Content C:\File1.xml 

पाठ मैं बदलना चाहते हैं xmlns है: xsi = "http: //www.w3। संगठन/2001/XMLSchema-instance " खाली स्ट्रिंग के साथ" "।

प्रश्न

  1. Can PowerShell बड़े फ़ाइलों को संभालने
  2. कैसे मैं कमांड लाइन
  3. PowerShell में महत्वपूर्ण ऑपरेटरों और प्रमुख ऑपरेटरों की सूची बचने के लिए वाक्य रचना से powershell स्क्रिप्ट कहते हैं शक्ति में शेल।
  4. मैं नहीं चाहता कि प्रतिस्थापन मेमोरी में हो और मानते हुए स्ट्रीमिंग पसंद करें जो सर्वर को पर घुटनों नहीं लाएगा।
  5. वहाँ किसी भी अन्य तरीकों मैं ले जा सकते हैं कर रहे हैं (विभिन्न उपकरण/रणनीति?)

धन्यवाद

उत्तर

3

यह यह पसंद नहीं करता क्योंकि आप एक फ़ाइल से नहीं पढ़ सकते हैं और कम से इसे वापस करने के लिए लिख गेट-कंटेंट/सेट-कंटेंट का उपयोग कर एक ही समय। मैं एक temp फ़ाइल का उपयोग करने की सलाह देता हूं और फिर अंत में, file1.xml को file1.xml.bak पर पुनर्नामित करें और temp फ़ाइल को file1.xml में पुनर्नामित करें।

  1. हाँ जब तक आप पूरी फ़ाइल को एक बार में लोड करने का प्रयास नहीं करते हैं। लाइन-बाय-लाइन काम करेगी लेकिन थोड़ी धीमी गति से चल रही है। -ReadCount पैरामीटर का उपयोग करें और प्रदर्शन को बेहतर बनाने के लिए इसे 1000 पर सेट करें।
  2. कौन सा कमांड लाइन? शक्ति कोशिका? यदि ऐसा है तो आप .\myscript.ps1 जैसे अपनी स्क्रिप्ट का आह्वान कर सकते हैं और यदि यह पैरामीटर लेता है तो c:\users\joe\myscript.ps1 c:\temp\file1.xml
  3. सामान्य रूप से regexes के लिए मैं एकल उद्धरण का उपयोग करता हूं यदि आपको PowerShell चर के संदर्भ में आवश्यकता नहीं है। फिर आपको केवल रेगेक्स से बचने की चिंता करने की आवश्यकता है और पावरशेल भी भाग नहीं रहा है। यदि आपको डबल-कोट्स का उपयोग करने की आवश्यकता है तो बैक-टिक चरित्र डबल-कोट्स में एस्केप चार है। "$ p1 $ ps1 पर सेट है"। आपके उदाहरण में एकल उद्धरण आपके रेगेक्स को सरल बनाता है (नोट: फॉरवर्ड स्लेश रेगेक्स में मेटाएक्टैक्टर्स नहीं हैं):

    'xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"

  4. बिल्कुल आप इसे स्ट्रीम करना चाहते हैं क्योंकि 50 जीबी स्मृति में फिट नहीं होगा। हालांकि, यदि आप लाइन-बाय-लाइन को संसाधित करते हैं तो यह एक मुद्दा बनता है। क्या होगा यदि आप जिस पाठ को प्रतिस्थापित करना चाहते हैं वह कई लाइनों में विभाजित है?

  5. यदि आपके पास स्प्लिट लाइन समस्या नहीं है तो मुझे लगता है कि पावरशेल इसे संभाल सकता है।
+1

@Keith, तुम सच में PowerShell पर भरोसा;) मैं शायद होगा OutOfMemoryException के बारे में चिंता करें क्योंकि 50 जीबी छोटी मेमोरी लीक इकट्ठा करने के लिए काफी बड़ा है .. बस एक अनुमान है। व्यक्तिगत रूप से मैं सीधे 'फ़ाइल। ओपन' का उपयोग करता हूं और स्ट्रीम के साथ काम करता हूं और मैन्युअल रूप से तुलना करता हूं (कोई regex)। – stej

+0

और ऐसा करने के लिए किसी को कुछ प्रकार के एक्सएमएल एपीआई का उपयोग नहीं करना चाहिए? सिर्फ एक विचार। डैनो यदि SAX या StAX .NET में उपलब्ध हैं; मैं एक्सएमएल के साथ बहुत ही कम काम करता हूं, लेकिन एक स्ट्रिंग करने से इसके लिए गलत लगता है। – Joey

+0

.NET में केवल एकमात्र, कर्सर शैली पाठक (XmlReader/XmlTextReader) है - एक पुल तंत्र जो SAX पुश दृष्टिकोण से थोड़ा अलग है। यह थोड़ा कठिन है लेकिन जाने का एक अच्छा तरीका है जब पूरा एक्सएमएल दस्तावेज़ स्मृति में फिट नहीं होगा। –

-1

एस्केप वर्ण powershell तार में बैकटिक (`), नहीं बैकस्लेश (\) है। मैं एक उदाहरण दूंगा, लेकिन विकी मार्कअप द्वारा बैकटिक का भी उपयोग किया जाता है। । अवधि और इस तरह के बिना ठीक होना चाहिए

9

मैं एक ऐसी ही जरूरत थी (और powershell अनुभव के समान कमी), लेकिन पत्थर की एक साथ एक पूरा जवाब - :(

केवल एक चीज आप से बचने के लिए होना चाहिए उद्धरण है इस पृष्ठ के अन्य उत्तरों से थोड़ा और अधिक शोध।

मैं भी रेगेक्स प्रोसेसिंग से बचना चाहता था, क्योंकि मुझे इसकी आवश्यकता नहीं थी - बस एक साधारण स्ट्रिंग को प्रतिस्थापित करता है - लेकिन एक बड़ी फ़ाइल पर, मैं इसे स्मृति में लोड नहीं करना चाहता था।

यहां मैंने जो आदेश दिया है (पठनीयता के लिए लाइनब्रैक जोड़ना):

Get-Content sourcefile.txt 
    | Foreach-Object {$_.Replace('http://example.com', 'http://another.example.com')} 
    | Set-Content result.txt 

पूरी तरह से काम किया! कभी भी ज्यादा मेमोरी को चूसना नहीं था (यह स्पष्ट रूप से पूरी फाइल को स्मृति में लोड नहीं करता था), और कुछ ही मिनटों के साथ बस चिपकाया गया।

+0

ने 3.5 जीबी रैम लिया। जब मैंने इसे मार दिया तो 30% सीपीयू। – Tilo

+0

शायद ** - रीडकाउंट ** या ** - रॉ ** http://www.happysysadm.com/2014/10/reading-large-text-files-with-powershell.html – Tilo

0

यह उस पर मेरी ले रहा है, अन्य उत्तर यहाँ से कुछ पर निर्माण:

Function ReplaceTextIn-File{ 
    Param(
    $infile, 
    $outfile, 
    $find, 
    $replace 
) 

    if(-Not $outfile) 
    { 
    $outfile = $infile 
    } 

    $temp_out_file = "$outfile.temp" 

    Get-Content $infile | Foreach-Object {$_.Replace($find, $replace)} | Set-Content $temp_out_file 

    if(Test-Path $outfile) 
    { 
    Remove-Item $outfile 
    } 

    Move-Item $temp_out_file $outfile 
} 

और इसलिए की तरह कहा जाता है:

ReplaceTextIn-File -infile "c:\input.txt" -find 'http://example.com' -replace 'http://another.example.com' 
संबंधित मुद्दे