วิธีค้นหาสตริงในหลายไฟล์และส่งคืนชื่อไฟล์ใน Powershell ได้อย่างไร


303

ฉันได้เริ่มเรียนรู้การใช้งาน powerhell เมื่อสองสามวันที่ผ่านมาและฉันไม่พบสิ่งใดบน google ที่ทำสิ่งที่ฉันต้องการดังนั้นโปรดอดทนกับคำถามของฉัน

ฉันถูกขอให้แทนที่สตริงข้อความบางไฟล์เป็นหลายไฟล์ ฉันไม่จำเป็นต้องทราบว่าส่วนขยายของไฟล์เป้าหมายที่เป็นไปได้และฉันไม่ทราบตำแหน่งของไฟล์เหล่านั้น จนถึงตอนนี้ฉันมีการจัดการเพื่อเรียกดูซ้ำในไดเรกทอรี ( get-ChildItem -recurse) และค้นหาสตริงที่ฉันกำลังมองหาด้วย get-content และ select-string:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

ปัญหาคือฉันสามารถดูข้อความที่ฉันกำลังมองหาได้ แต่ฉันไม่รู้ว่าจะบอกให้ PS ส่งคืนพา ธ และชื่อของทุกไฟล์ที่ตรงกันได้อย่างไร

ฉันจะรับชื่อและตำแหน่งของไฟล์ที่มีนิพจน์ที่ฉันกำลังค้นหาได้อย่างไร


2
อาจแก้ไขคำถามให้กว้างขึ้น คำตอบสำหรับคำถามนี้มีอะไรจะทำอย่างไรกับ JBoss หรือโปรแกรมที่คุณกำลังทำงานอยู่นั้นดูเหมือนว่า ...
Kolob แคนยอน

5
ฉันเพิ่งเห็นความคิดเห็นของคุณและแก้ไขคำถามของฉัน ... 2 ปีต่อมา! ดีกว่าไม่สาย .. :)
บลูซ

คำตอบ:


468

สิ่งนี้ควรระบุตำแหน่งของไฟล์ที่มีรูปแบบของคุณ:

Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path

3
จะทำอย่างไรถ้าคุณต้องการย้ายไฟล์เหล่านั้นด้วย ... ฉันได้รับข้อผิดพลาดเกี่ยวกับสิ่งนี้ซึ่งฉันไม่สามารถเข้าร่วม | ย้ายรายการไปที่ส่วนท้ายของ
rud3y

6
รายการย้ายไม่มีnameพารามิเตอร์ ลองเพิ่ม| %{Move-Item $_.name <destination>}
jon Z

49
Get-ChildItem -Recurse | Select-String "dummy" -List | Select Pathผลตอบแทนเพียงนัดแรกสำหรับแต่ละไฟล์นั้นอาจจะเป็นเพียงเล็กน้อยที่มีประสิทธิภาพมากขึ้นและหลีกเลี่ยงความจำเป็นให้กับกลุ่มพวกเขา
เบน

5
เป็นที่น่าสังเกตว่าคุณสามารถกรองไฟล์บางประเภทได้เท่านั้นพูดtxtไฟล์ถ้าคุณใช้Get-ChildItem -Recurse -Filter *.txtแทน
Girardi

@ rud3y ฉันขอแนะนำให้คุณเขียนมันออกมาเป็นสคริปต์โดยใช้การforeachวนซ้ำถ้าคุณใช้การทำงานขนาดใหญ่แบบนั้น มันซับซ้อนมากเมื่อคุณพยายามทำทั้งหมดในบรรทัดเดียวและมันง่ายมากที่จะทำผิดพลาดใหญ่ ฉันพูดจากประสบการณ์
Kolob Canyon

74

มีคำตอบที่ถูกต้องหลากหลายรูปแบบที่นี่ แต่นี่เป็นรหัสที่กระชับที่สุดสำหรับรูปแบบที่แตกต่างหลากหลาย สำหรับแต่ละรูปแบบบรรทัดบนสุดจะแสดงไวยากรณ์แบบเต็มและด้านล่างแสดงไวยากรณ์แบบสั้น

Item (2) เป็นรูปแบบที่กระชับกว่าของคำตอบจาก Jon Z และ manojlds ในขณะที่ item (1) เทียบเท่ากับคำตอบจาก vikas368 และ buygrush

  1. รายการวัตถุFileInfoสำหรับไฟล์ทั้งหมดที่มีรูปแบบ:

    Get-ChildItem -Recurse filespec | Where-Object { Select-String pattern $_ -Quiet }
    ls -r filespec | ? { sls pattern $_ -q }
    
  2. รายการชื่อไฟล์สำหรับไฟล์ทั้งหมดที่มีรูปแบบ:

    Get-ChildItem -Recurse filespec | Select-String pattern | Select-Object -Unique Path
    ls -r filespec | sls pattern | select -u Path
    
  3. รายการวัตถุFileInfoสำหรับไฟล์ทั้งหมดที่ไม่มีรูปแบบ:

    Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }
    ls -r filespec | ? { !(sls pattern $_ -q) }
    
  4. รายการชื่อไฟล์สำหรับไฟล์ทั้งหมดที่ไม่มีรูปแบบ:

    (Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }).FullName
    (ls -r filespec | ? { !(sls pattern $_ -q) }).FullName
    

นอกจากนี้หากคุณกำลังมองหาไฟล์ที่มีรูปแบบที่ใดก็ได้คุณสามารถยอมแพ้หลังจากค้นหาอินสแตนซ์แรกโดยใช้-Listพารามิเตอร์ของSelect-String
KyleMit

ฉันหวังว่าผู้ปฏิบัติการจะถามคำถามที่แตกต่างกันเล็กน้อยเพื่อให้นี่เป็น AA # 1 มีประโยชน์มากและเห็นได้ชัดว่า @Michael Sorens groks PS!
cBlaine

20

สิ่งนี้จะแสดงเส้นทางชื่อไฟล์และบรรทัดเนื้อหาที่พบซึ่งตรงกับรูปแบบ

Get-ChildItem -Path d:\applications\*config -recurse |  Select-String -Pattern "dummy" 

หากสามารถเพิ่มบรรทัดระหว่างผลลัพธ์ได้ :)
cladelpino

15

ท่อเนื้อหาของคุณ

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

ถึง fl *

คุณจะเห็นว่าเส้นทางกำลังถูกส่งคืนเป็นคุณสมบัติของวัตถุแล้ว

หากคุณต้องการเพียงเส้นทางใช้select pathหรือselect -unique pathลบรายการที่ซ้ำ:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy" | select -unique path

1
ขอบคุณคุณทั้งคู่นี่คือสิ่งที่ฉันกำลังมองหา น่าเสียดายที่เมื่อมีไดเรกทอรีย่อยมากมายที่เกี่ยวข้องกับเส้นทาง PS จะตัดเส้นทางสัมบูรณ์และเพิ่มจุดสามจุดที่จุดสิ้นสุดของบรรทัดเช่น \ dir1 \ dir2 \ dir3 \ path ... ดังนั้นฉันจึงไม่รู้ว่าไฟล์ใดถูกส่งคืน . มีวิธีที่จะบอก PS ให้โลภน้อยกว่าตัวละครและรำคาญที่แสดงเส้นทางเต็มหรือไม่? :) ขอบคุณมาก !
Bluz

3
คุณต้องเพิ่ม-Fileสวิตช์ไปGet-ChildItemหรือคุณจบลงด้วยข้อผิดพลาดที่ไม่สิ้นสุดจากการพยายามโทรหาGet-Contentไดเรกทอรี
RubberDuck

หากคุณต้องการเส้นทางแบบเต็มคุณสามารถทำสิ่งนี้(Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy").FullNameคนดูเหมือนจะลืม PowerShell เป็นเชิงวัตถุ เมื่อมีข้อสงสัยให้มองหาอสังหาริมทรัพย์
Kolob Canyon

10

นี่คือวิธีที่ฉันจะทำคุณไม่จำเป็นต้องได้รับเนื้อหา:

ls -r | Select-String dummy | select line,path

หรือ

ls -r | Select-String dummy | fl *

เพื่อดูว่าคุณสมบัติที่แตกต่างคืออะไร ...

เร็วกว่านี้ อาร์กิวเมนต์ที่สองคือ -filter:

ls -r . *.bat | select-string netsh

2
+1, ใช้งานได้ดีกับเคสของฉัน แต่ใช้select Pattern, LineNumber, Filenameเพื่อผลลัพธ์ที่กระชับยิ่งขึ้น Line ส่งคืนทุกอย่างในบรรทัดที่มีสตริงรูปแบบของคุณ คุณสามารถส่งออกสิ่งนี้ไปยัง csv ได้อย่างง่ายดายหากคุณต้องการ
Protonova

9
Get-ChildItem -r | ? {$_.psiscontainer -eq $false} | ? {gc $_.pspath |select-string -pattern "dummy"}

นี้จะให้รายละเอียดของไฟล์ทั้งหมด


ทั้งหมดไม่รู้ว่าใช้-rงานได้ คิดว่าคุณต้องทำเสมอ-Recurse
Kolob Canyon

5

เพื่อให้รายละเอียดไฟล์สมบูรณ์ในแถวลำดับคุณสามารถใช้คำตอบที่โพสต์โดย vikas368 เล็กน้อย (ซึ่งดูเหมือนว่าจะใช้งานไม่ได้กับระบบเติมข้อความอัตโนมัติ ISE):

Get-ChildItem -Recurse | Where-Object { $_ | Select-String -Pattern "dummy" }

หรือสั้น:

ls -r | ?{ $_ | Select-String -Pattern "dummy" }

5

หากคุณค้นหาในไดเรกทอรีเดียวคุณสามารถทำได้:

select-string -Path "c:\temp\*.*" -Pattern "result"  -List | select Path

4

นี่จะแสดงรายการพา ธ แบบเต็มไปยังแต่ละไฟล์ที่มีสตริงการค้นหา:

foreach ($file in Get-ChildItem | Select-String -pattern "dummy" | Select-Object -Unique path) {$file.path}

โปรดทราบว่าจะไม่แสดงส่วนหัวเหนือผลลัพธ์และจะไม่แสดงบรรทัดข้อความที่มีสตริงการค้นหา ทั้งหมดนี้จะบอกคุณว่าคุณอยู่ที่ไหนที่คุณสามารถค้นหาไฟล์ที่มีสตริง


2
แนวคิดใดบ้างที่จะแสดงหมายเลขบรรทัดที่พบรูปแบบพร้อมกับชื่อไฟล์
Piotr L

4

ฉันแก้ไขหนึ่งในคำตอบข้างต้นเพื่อให้ข้อมูลเพิ่มเติมเล็กน้อย สิ่งนี้ทำให้ฉันเคียวรีที่สองในภายหลัง มันเป็นอะไรแบบนี้:

Get-ChildItem `
        -Path "C:\data\path" -Filter "Example*.dat" -recurse | `
    Select-String -pattern "dummy" | `
    Select-Object -Property Path,LineNumber,Line | `
    Export-CSV "C:\ResultFile.csv"

ฉันสามารถระบุพา ธ และสัญลักษณ์แทนไฟล์ด้วยโครงสร้างนี้และบันทึกชื่อไฟล์หมายเลขบรรทัดและบรรทัดที่เกี่ยวข้องไปยังไฟล์เอาต์พุต


เย็น! ขอบคุณสำหรับโซลูชันเพิ่มเติมนี้ :) อย่างไรก็ตามคุณสามารถลิงค์ไปยังคำตอบที่คุณยึดตามโซลูชันของคุณและตั้งชื่อผู้แต่งคำตอบนั้นเพื่อให้เครดิตได้หรือไม่? ขอบคุณ!
Max Vollmer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.