ค้นหาไฟล์วนซ้ำโดยใช้ PowerShell


238

ฉันกำลังค้นหาไฟล์ในโฟลเดอร์ทั้งหมด

Copyforbuild.bat มีให้บริการในหลายสถานที่และฉันต้องการค้นหาแบบเรียกซ้ำ

$File = "V:\Myfolder\**\*.CopyForbuild.bat"

ฉันจะทำใน PowerShell ได้อย่างไร

คำตอบ:


393

ใช้Get-ChildItem cmdlet กับ-Recurseสวิตช์:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force

1
ดูเหมือนว่าจะมีปัญหาที่ถ้ามันทำงานในไดเรกทอรีที่คุณไม่ได้รับอนุญาตให้เข้าถึงการค้นหาทั้งหมดจะถูกยกเลิกเนื่องจากกระบวนการออกจาก มีวิธีแก้ไขไหม?
deed02392

6
ลองตั้งค่าพารามิเตอร์ ErrorAction เป็น Continue หรือ SilentlyContinue (ในกรณีที่ค่าไม่ได้กล่าวถึง)
Shay Levy

22
วิธีที่สั้นกว่าในการทำสิ่งเดียวกัน: cd V:\MyFolderตามด้วยls -r -inc CopyForBuild.bat
Orion Edwards

8
ดังนั้นสิ่งที่ผู้แสดงความคิดเห็นข้างต้นมีความหมายคือ ...ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }
Andrew

ฉันปรับคำตอบนี้ให้ทำสตริงบางส่วนโดยเพิ่มสัญลักษณ์ astric ( *) ที่ส่วนท้ายของชื่อไฟล์ ****** LINE1: $File = "Microsoft.OData.Core.NetFX35.V7*"LINE2: $Folder = "C:\Program Files"LINE3:Get-ChildItem -Path $Folder -Filter $File -Recurse -ErrorAction SilentlyContinue -Force
SherlockSpreadsheets

37

ฉันใช้สิ่งนี้เพื่อค้นหาไฟล์จากนั้นให้ PowerShell แสดงเส้นทางทั้งหมดของผลลัพธ์:

dir -Path C:\FolderName -Filter FileName.fileExtension -Recurse | %{$_.FullName}

คุณสามารถใช้สัญลักษณ์แทน*ในFolderNameFileName.fileExtensionและ / หรือ ตัวอย่างเช่น:

dir -Path C:\Folder* -Filter File*.file* -Recurse | %{$_.FullName}

ตัวอย่างด้านบนจะค้นหาโฟลเดอร์ใด ๆ ใน C:\Folderไดรฟ์เริ่มต้นด้วยคำว่า ดังนั้นหากคุณมีชื่อโฟลเดอร์FolderFooและFolderBarPowerShell จะแสดงผลลัพธ์จากทั้งสองโฟลเดอร์

เช่นเดียวกับชื่อไฟล์และนามสกุลไฟล์ หากคุณต้องการค้นหาไฟล์ที่มีนามสกุล แต่ไม่ทราบชื่อของไฟล์คุณสามารถใช้:

dir -Path C:\FolderName -Filter *.fileExtension -Recurse | %{$_.FullName}

หรือในทางกลับกัน:

dir -Path C:\FolderName -Filter FileName.* -Recurse | %{$_.FullName}

4
ฉันพบว่าคำตอบนี้มีประโยชน์อย่างยิ่งเพราะมันระบุถึงกรณีการใช้งานเฉพาะ - จริง ๆ แล้วต้องการใช้ไฟล์ที่คุณกำลังค้นหา The | เพื่อให้คุณชื่อเต็มของไฟล์เป็นสิ่งที่ขาดหายไปในคำตอบอื่น ๆ
นักพัฒนา Newteq

1
ฉันต้องยอมรับกับ @ Sanity1123 ที่นี่หากคุณต้องการใช้ไฟล์จริงคุณจะต้องใช้พา ธ แบบเต็มไปยังไฟล์ IMHO นี่ควรเป็นคำตอบที่ยอมรับได้
uceumern

31

เมื่อค้นหาโฟลเดอร์ที่คุณอาจได้รับข้อผิดพลาดตามความปลอดภัย (เช่นC:\Users) ให้ใช้คำสั่งต่อไปนี้:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force

12
Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat

ก็จะได้ผล


และถ้าคุณต้องการส่งออกผลลัพธ์ไปยังไฟล์คุณสามารถเพิ่ม `> path_to_filename.txt` ที่ส่วนท้ายของคำสั่ง
เกวน Au

7

นี่คือวิธีการที่ฉันคิดขึ้นมาหลังจากที่ต้องดิ้นรน:

Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*

ในการทำให้ตัวล้างเอาต์พุต (พา ธ เท่านั้น) ใช้:

(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname

เพื่อให้ได้ผลลัพธ์แรกเท่านั้นให้ใช้:

(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname | Select -First 1

ตอนนี้สำหรับสิ่งที่สำคัญ:

เพื่อค้นหาเฉพาะไฟล์ไดเรกทอรี / ไม่ได้ใช้-Fileหรือ-Directory(ดูด้านล่างทำไม) ใช้สิ่งนี้แทนไฟล์:

Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}

และลบ-eq $falseไดเรกทอรีสำหรับ อย่าได้bin/*ปล่อยให้ตัวแทนต่อท้ายเช่น

ทำไมไม่ใช้สวิตช์ในตัว พวกมันแย่มากและลบคุณสมบัติแบบสุ่ม ตัวอย่างเช่นเพื่อใช้-Includeกับไฟล์คุณต้องจบเส้นทางด้วย wildcard อย่างไรก็ตามสิ่งนี้ปิดใช้งาน-Recurseสวิตช์โดยไม่บอกคุณ:

Get-ChildItem -File -Recurse -Path ./bin/* -Include *.lib

คุณคิดว่าจะให้ทุกคน*.libในไดเรกทอรีย่อยทั้งหมด แต่จะค้นหาเฉพาะในระดับสูงสุดbinเท่านั้น

เพื่อค้นหาไดเรกทอรีคุณสามารถใช้ -Directoryแต่คุณต้องลบ wildcard ที่ต่อท้าย -Recurseสำหรับเหตุผลใดนี้จะไม่ยกเลิกการใช้งาน ด้วยเหตุผลเหล่านี้ฉันจึงไม่แนะนำให้ใช้ธงบิวอิน

คุณสามารถย่อคำสั่งนี้ให้สั้นลงได้มาก:

Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}

กลายเป็น

gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}
  • Get-ChildItem มีนามแฝงว่า gci
  • -Path เป็นค่าเริ่มต้นที่ตำแหน่ง 0 ดังนั้นคุณสามารถสร้างเส้นทางอาร์กิวเมนต์แรกได้
  • -Recurse มีนามแฝงว่า -s
  • -Include ไม่มีชวเลข
  • ใช้เครื่องหมายคำพูดเดี่ยวสำหรับช่องว่างในชื่อ / พา ธ เพื่อให้คุณสามารถล้อมรอบคำสั่งทั้งหมดด้วยเครื่องหมายคำพูดคู่และใช้ในเครื่องหมายคำสั่ง การทำในลักษณะอื่น (ล้อมรอบด้วยเครื่องหมายคำพูดเดี่ยว) ทำให้เกิดข้อผิดพลาด

6

ลองสิ่งนี้:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}

2
นอกจากนี้คุณยังสามารถใช้| Where-Object { !$_PSIsContainer }เพื่อแยกโฟลเดอร์
Gargravarr

5

กรองโดยใช้สัญลักษณ์แทน:

Get-ChildItem -Filter CopyForBuild* -Include *.bat,*.cmd -Exclude *.old.cmd,*.old.bat -Recurse

การกรองโดยใช้นิพจน์ทั่วไป:

Get-ChildItem -Path "V:\Myfolder" -Recurse
| Where-Object { $_.Name -match '\ACopyForBuild\.[(bat)|(cmd)]\Z' }

1
มันไม่ควรจะเป็น'\ACopyForBuild\.(bat|cmd)\Z'?
E. Sundin

1

หากต้องการเพิ่ม @ user3303020 คำตอบและแสดงผลลัพธ์การค้นหาลงในไฟล์คุณสามารถเรียกใช้

Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat > path_to_results_filename.txt

การค้นหาไฟล์ที่ถูกต้องนั้นอาจทำได้ง่ายกว่า

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