複数のファイルで文字列を検索し、Powershellでファイルの名前を返す方法は?


303

私は2日前にpowershellの学習を開始しましたが、必要なことを行うものをGoogleで見つけることができなかったので、私の質問に耐えてください。

一部のテキスト文字列を複数のファイルに置き換えるように依頼されました。私は必ずしも可能なターゲットファイルの拡張子を知っているわけではなく、それらの場所も知りません。これまでのところ、ディレクトリ(get-ChildItem -recurse)を再帰的に参照して、get-contentおよびselect-stringで探していた文字列を見つけることができました。

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

問題は、探しているテキストの出現を確認できますが、一致するすべてのファイルのパスと名前も返すようにPSに指示する方法がわかりません。

探している式を含むファイルの名前と場所を取得するにはどうすればよいですか?


2
質問をより一般的になるように編集してください。この質問への答えは、JBossやあなたが取り組んでいるアプリケーションとは何の関係もないようです...
Kolob Canyon

5
私はあなたのコメントを見つけて私の質問を編集しました... 2年後!決して遅くないより良い.. :)
Bluz

回答:


469

これにより、パターンを含むファイルの場所がわかります。

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

3
これらのファイルも移動したい場合はどうしますか?...これに参加できないというエラーが発生します| Move-Itemをその最後に移動します。
rud3y 2012

6
Move-Itemにはnameパラメーターがありません。追加してみてください| %{Move-Item $_.name <destination>}
jon Z

49
Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path各ファイルの最初の一致のみを返すので、少し効率的であり、それらをグループ化する必要がありません
2015

5
代わりにtxt使用する場合は、特定のファイルタイプ(ファイルなど)のみをフィルターに掛けることができることに注意してくださいGet-ChildItem -Recurse -Filter *.txt
Girardi

@ rud3yこのforeachような大規模な操作を行う場合は、ループを使用してスクリプトで記述することを強くお勧めします。これらすべてを1行で実行しようとすると、非常に複雑になり、大きな間違いを犯しやすくなります。私は経験から話します
Kolob Canyon

75

ここにはさまざまな正確な答えがありますが、ここにいくつかの異なるバリエーションの最も簡潔なコードがあります。バリエーションごとに、上の行は完全な構文を示し、下の行は簡潔な構文を示しています。

項目(2)はJon Zとmanojldsからの回答のより簡潔な形式ですが、項目(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
    

また、パターンがどこかに含まれているファイルを探しているだけの場合は-ListSelect-String
KyleMit

これがAAになるように、OPが質問のわずかなバリエーションを求めていれば幸いです。#1は非常に役に立ち、@ Michael SorensがPSを成長させていることは明らかです。
cBlaine 2015

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のように行末に3つのドットを追加するので、返されるファイルがわかりません。 。PSにキャラクターへの欲張りを抑え、フルパスを表示するように指示する方法はありますか?:) どうもありがとう !
Bluz

3
-Fileスイッチをに追加する必要がありGet-ChildItemますGet-Content。そうしないと、ディレクトリを呼び出そうとすることによるエラーのカスケードが終わることはありません。
RubberDuck 2016

フルパスが必要な場合は、これを行うことができます(Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy").FullName。PowerShellがオブジェクト指向であることを忘れているようです。疑問がある場合は、物件を探してください
コロブキャニオン2018

10

これは私がやる方法です、あなたはget-contentを必要としません:

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

または

ls -r | Select-String dummy | fl *

さまざまなプロパティを確認するには...

これはより高速です。2番目の引数は-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
考え出した

5

結果の配列で完全なファイルの詳細を保持するには、vikas368によって投稿された回答をわずかに変更します(これはISEオートコンプリートではうまく機能しないようです)。

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

要するに:

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

5

1つのディレクトリを検索すると、次のようにできます。

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

上記の回答の1つを変更して、もう少し情報を提供しました。これにより、後で2番目のクエリを回避できました。それはこのようなものでした:

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.