PowerShell का उपयोग करके निर्देशिका में फ़ाइलों के माध्यम से लूप करें


243

मैं निर्देशिका में सभी .log फ़ाइलों को देखने के लिए निम्न कोड को कैसे बदल सकता हूं और केवल एक फ़ाइल को नहीं?

मुझे सभी फ़ाइलों के माध्यम से लूप करने की आवश्यकता है और उन सभी लाइनों को हटा दें जिनमें "चरण 4" या "चरण 9" शामिल नहीं हैं। वर्तमान में यह एक नई फ़ाइल बनाएगा, लेकिन मुझे यकीन नहीं है कि for eachयहां लूप (नौसिखिया) का उपयोग कैसे किया जाए ।

वास्तविक फ़ाइलों को इस तरह नामित किया गया है: 2013 09 03 00_01_29.log । मैं आउटपुट फ़ाइलों को या तो उन्हें अधिलेखित करना चाहता हूं, या समान नाम, "आउट" के साथ जोड़ा जाना चाहिए।

$In = "C:\Users\gerhardl\Documents\My Received Files\Test_In.log"
$Out = "C:\Users\gerhardl\Documents\My Received Files\Test_Out.log"
$Files = "C:\Users\gerhardl\Documents\My Received Files\"

Get-Content $In | Where-Object {$_ -match 'step4' -or $_ -match 'step9'} | `
Set-Content $Out

जवाबों:


363

इसे आजमाइए:

Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files" -Filter *.log | 
Foreach-Object {
    $content = Get-Content $_.FullName

    #filter and save content to the original file
    $content | Where-Object {$_ -match 'step[49]'} | Set-Content $_.FullName

    #filter and save content to a new file 
    $content | Where-Object {$_ -match 'step[49]'} | Set-Content ($_.BaseName + '_out.log')
}

धन्यवाद। बेसनेम भाग काम नहीं करता है (संस्करण 1) - लेकिन मैंने पहले पूर्ण फ़ाइल का बैकअप बनाकर और फिर मूल फ़ाइल में परिवर्तन करके प्रबंधित किया।
user2725402

6
V1 के लिए, आप आधार नाम निकालने के लिए निम्नलिखित का उपयोग कर सकते हैं: [io.path] :: GetFileNameWithoutExtension ($ नाम)
Shay Levy

अगर मैं अपनी जगह BaseNameसे हट जाऊं तो मुझे FullNameवही मिलेगा जो मैं चाहता हूं।
M--

78

एक निर्देशिका की सामग्री प्राप्त करने के लिए आप इसका उपयोग कर सकते हैं

$files = Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\"

तो आप इस चर पर भी पा सकते हैं:

for ($i=0; $i -lt $files.Count; $i++) {
    $outfile = $files[$i].FullName + "out" 
    Get-Content $files[$i].FullName | Where-Object { ($_ -match 'step4' -or $_ -match 'step9') } | Set-Content $outfile
}

इसे लगाने का एक और भी आसान तरीका है foreachलूप (@Soapy और @MarkSchultheiss का धन्यवाद):

foreach ($f in $files){
    $outfile = $f.FullName + "out" 
    Get-Content $f.FullName | Where-Object { ($_ -match 'step4' -or $_ -match 'step9') } | Set-Content $outfile
}

यह "out.log" नामक एक आउटपुट फ़ाइल बनाता है। मैं प्रत्येक इनपुट फ़ाइल के लिए एक अलग आउटपुट फ़ाइल कैसे बना सकता हूं?
user2725402

@ user2725402 मैंने एक इनपुट आश्रित आउटपुट फ़ाइल जोड़ी है जिसका नाम है <इनपुट फ़ाइल का नाम> आउट
पीवीइट

मुझे यकीन नहीं है कि मैं क्या गलत कर रहा हूं, लेकिन यह काम नहीं कर रहा है - मुझे अब कोई आउटपुट फाइल नहीं मिल रही है (और कोई त्रुटि नहीं):$files = Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\" $files | Where-Object { $outFile = $_.Name + "out" Get-Content $_.FullName | Where-Object { $_ -match 'step4' -or $_ -match 'step9' } | Set-Content $outFile }
user2725402

2
आप यह भी कर सकते हैंforeach ($f in Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\") { ... }
१००

1
या उपयोगForEach ($f in $files){...}
मार्क शुल्त्स

31

यदि आपको किसी विशेष प्रकार की फ़ाइल के लिए किसी निर्देशिका के अंदर लूप करने की आवश्यकता है, तो नीचे दिए गए कमांड का उपयोग करें, जो docफ़ाइल प्रकार की सभी फ़ाइलों को फ़िल्टर करता है

$fileNames = Get-ChildItem -Path $scriptPath -Recurse -Include *.doc

यदि आपको कई प्रकारों पर फ़िल्टर करने की आवश्यकता है, तो नीचे दिए गए कमांड का उपयोग करें।

$fileNames = Get-ChildItem -Path $scriptPath -Recurse -Include *.doc,*.pdf

अब $fileNamesचर एक सरणी के रूप में कार्य करते हैं जिससे आप अपने व्यापारिक तर्क को लूप और लागू कर सकते हैं।


मुझे किस चीज़ ने छिपाया और / या सिस्टम फ़ाइलों की चूक थी। यह देखने के लिए कि आपको -ForceGet-ChildItem के पैरामीटर का उपयोग करना है । इसका डॉक्स dmic.microsoft.com/en-us/powershell/module/… पर देखें ।
til_b

-6

अन्य उत्तर महान हैं, मैं बस जोड़ना चाहता हूं ... PowerShell में प्रयोग किया जाने वाला एक अलग तरीका: GNUWin32 बर्तन स्थापित करें और लाइनों को देखने के लिए grep का उपयोग करें / http://gnuwin32.sourceforge.net/ फाइल करने के लिए आउटपुट रीडायरेक्ट करें

यह हर बार नई फ़ाइल को अधिलेखित करता है:

grep "step[49]" logIn.log > logOut.log 

यदि आप लॉग इन फ़ाइल को अधिलेखित करते हैं और डेटा रखना चाहते हैं, तो यह लॉग आउटपुट को जोड़ता है:

grep "step[49]" logIn.log >> logOut.log 

नोट: विश्व स्तर पर GNUWin32 बर्तनों का उपयोग करने में सक्षम होने के लिए आपको अपने सिस्टम पथ में बिन फ़ोल्डर जोड़ना होगा।


18
इस प्रश्न को PowerShell के रूप में टैग किया गया था, न कि यूनिक्स
स्टीव सीपी

2
हाँ। जाहिर है। मेरा लेना काफी सरल था: आप विंडोज में GNUWin32 के बर्तनों का उपयोग कर सकते हैं इसलिए आप Powershell में * nix टूल्स का आसानी से उपयोग कर सकते हैं। काम करता है। किसी ने कभी नहीं कहा, कि उत्तर को पूरी तरह से पॉवरशेल का मूल निवासी होना चाहिए। और यहां तक ​​कि अगर उन्होंने किया, तो आप अभी भी Win32 Utils को Powershell से सीधे कॉल कर सकते हैं। उपलब्ध और संगत का उपयोग करके AFAIK वास्तव में एक बुरी चीज नहीं है।
user1628658

2
मैंने अपनी पिछली टिप्पणी संपादित कर ली होगी, लेकिन मैंने 5 मिनट की सीमा पार कर दी: स्टीवसी: क्या आप कह रहे हैं कि जीएनयू टूल्स को शामिल करना जो विंडोज के तहत ठीक काम करते हैं, किसी तरह पॉवरशेल को धता बता रहे हैं? यह एक बात है। मैं समझता हूं कि पॉवरशेल में शुद्ध रूप से काम करने से अल्पावधि में अधिक उत्पादन हो सकता है। लंबी अवधि में संभावनाओं का विस्तार वास्तव में अधिक योग्यता है। आप अधिक विकल्प जोड़ते हैं और पूरी तरह से विंडोज और पॉवर्सशेल में बिना किसी लिनक्स एमुलेटर जैसे सिग्विन के साथ काम कर रहे हैं। इसलिए जब मैं आपका आरक्षण समझता हूं, मैं असहमत हूं।
user1628658

5
यह सवाल पॉवरशेल में देखने के बारे में था, न कि अन्य भाषाओं की भीड़ का इस्तेमाल किया जा सकता है।
7

1
प्रश्न का उत्तर प्रश्न से है। यह प्रश्न स्पष्ट था कि यह पावरशेल में उत्तर चाहता था। आपका उत्तर कुछ स्थापित किया गया था और इसका उपयोग करें। आप रूबी को स्थापित करने का सुझाव दे सकते हैं, आदि
स्टीव डिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.