วนรอบไฟล์ในไดเรกทอรีโดยใช้ PowerShell


243

ฉันจะเปลี่ยนรหัสต่อไปนี้เพื่อดูไฟล์. log ทั้งหมดในไดเรกทอรีและไม่ใช่แค่ไฟล์เดียวได้อย่างไร

ฉันต้องวนซ้ำไฟล์ทั้งหมดและลบทุกบรรทัดที่ไม่มี "step4" หรือ "step9" ปัจจุบันนี้จะสร้างไฟล์ใหม่ แต่ฉันไม่แน่ใจว่าจะใช้for eachลูปที่นี่ได้อย่างไร (มือใหม่)

ไฟล์ที่เกิดขึ้นจริงที่มีชื่อเช่นนี้: 2013 09 03 00_01_29.log ฉันต้องการไฟล์ที่ส่งออกเพื่อเขียนทับพวกเขาหรือมีชื่อ SAME ผนวกกับ "ออก"

$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')
}

ขอบคุณ ส่วน BaseName ใช้งานไม่ได้ (เวอร์ชั่น 1) - แต่ฉันจัดการโดยสร้างการสำรองข้อมูลไฟล์เต็มก่อนจากนั้นทำการเปลี่ยนแปลงไฟล์ต้นฉบับ
2725402

6
สำหรับ v1 คุณสามารถใช้ข้อมูลต่อไปนี้เพื่อแยกชื่อฐาน: [io.path] :: GetFileNameWithoutExtension ($ name)
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" ฉันจะสร้างไฟล์เอาต์พุตแยกต่างหากสำหรับไฟล์อินพุตแต่ละไฟล์ได้อย่างไร
2725402

@ user2725402 ฉันได้เพิ่มไฟล์เอาต์พุตการพึ่งพาอินพุทที่ชื่อ <input file name> out
PVitt

ไม่แน่ใจว่าสิ่งที่ฉันทำผิด แต่ไม่ได้ผล - ฉันไม่ได้รับไฟล์เอาต์พุต (และไม่มีข้อผิดพลาด): $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 }
2725402

2
คุณสามารถทำได้foreach ($f in Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\") { ... }
Soapy

1
หรือใช้ForEach ($f in $files){...}
Mark Schultheiss

31

หากคุณต้องการวนลูปภายในไดเรคทอรีสำหรับไฟล์ประเภทใดประเภทหนึ่งซ้ำให้ใช้คำสั่งด้านล่างซึ่งกรองdocไฟล์ประเภทไฟล์ทั้งหมด

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

หากคุณต้องการทำการกรองหลายประเภทให้ใช้คำสั่งด้านล่าง

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

ตอนนี้$fileNamesตัวแปรทำหน้าที่เป็นอาร์เรย์ที่คุณสามารถวนซ้ำและใช้ตรรกะทางธุรกิจของคุณ


สิ่งที่ฉัน bugged คือการละเลยของไฟล์ที่ซ่อนอยู่และ / หรือระบบ หากต้องการเห็นพวกเขาคุณต้องใช้-Forceพารามิเตอร์เพื่อรับ-ChildItem ดูเอกสารได้ที่docs.microsoft.com/en-us/powershell/module/
til_b

-6

คำตอบอื่น ๆ ที่ยอดเยี่ยมฉันแค่ต้องการเพิ่ม ... วิธีการที่แตกต่างกันที่ใช้งานได้ใน PowerShell: ติดตั้ง GNUWin32 utils และใช้ grep เพื่อดูบรรทัด / เปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์http://gnuwin32.sourceforge.net/

ไฟล์นี้จะเขียนทับไฟล์ใหม่ทุกครั้ง:

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

สิ่งนี้จะผนวกเอาท์พุทของบันทึกเพิ่มเติมในกรณีที่คุณเขียนทับไฟล์ logIn และต้องการเก็บข้อมูล:

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

หมายเหตุ: เพื่อให้สามารถใช้ GNUWin32 utils ได้ทั่วโลกคุณต้องเพิ่มโฟลเดอร์ bin ลงในพา ธ ระบบของคุณ


18
คำถามนี้ถูกแท็กเป็น PowerShell ไม่ใช่ Unix
SteveC

2
ใช่. อย่างชัดเจน การใช้ของฉันค่อนข้างง่าย: คุณสามารถใช้ GNUWin32 utils ใน Windows ดังนั้นคุณสามารถใช้เครื่องมือ * nix ใน Powershell ได้อย่างง่ายดาย โรงงาน ไม่มีใครเคยพูดว่าคำตอบต้องเป็นภาษาของ Powershell ทั้งหมด และแม้ว่าพวกเขาจะทำคุณยังสามารถเรียก Win32 Utils ได้โดยตรงจาก Powershell AFAIK ที่ใช้สิ่งที่มีอยู่และใช้งานร่วมกันได้ไม่ได้เป็นเรื่องเลวร้าย
user1628658

2
ฉันจะแก้ไขความคิดเห็นก่อนหน้าของฉัน แต่ฉันผ่านขีด จำกัด 5 นาที: SteveC: คุณกำลังบอกว่าการรวมเครื่องมือ GNU ที่ทำงานได้ดีกับ Windows ทำได้ดีกว่า Powershell หรือเปล่า? นั่นคือสิ่งหนึ่ง ฉันเข้าใจว่าการทำงานนี้อย่างหมดจดใน Powershell อาจมีประสิทธิผลมากกว่าในระยะสั้น ในระยะยาวการขยายความเป็นไปได้มีประโยชน์มากกว่าจริง ๆ คุณเพิ่มตัวเลือกเพิ่มเติมและทำงานอย่างสมบูรณ์ใน Windows และ Powershell โดยไม่มีตัวเลียนแบบ Linux เช่น Cygwin ดังนั้นในขณะที่ฉันเข้าใจการจองของคุณฉันไม่เห็นด้วย
user1628658

5
คำถามคือเกี่ยวกับการค้นหา PowerShell ไม่ใช่ภาษาอื่น ๆ ที่สามารถใช้ได้
SteveC

1
คำตอบนั้นมีไว้สำหรับคำถาม คำถามนี้ชัดเจนว่าต้องการคำตอบใน PowerShell คำตอบของคุณคือการติดตั้งบางสิ่งบางอย่างและใช้มัน คุณน่าจะแนะนำให้ติดตั้ง Ruby ฯลฯ
SteveC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.