できる限りすべてのPowershellコマンドを使用するのが好きです。少しテストした後、これが私ができる最善の方法です。
$source = "C:\test"
$destination = "C:\test2"
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"
$bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter}
foreach ($item in $bin) {Copy-Item -Path $item.FullName -Destination $destination}
最初の3行は、これを読みやすくするためのものです。必要に応じて、実際のコマンド内で変数を定義できます。このコードサンプルの要点は、正規表現の一致を受け入れるフィルターである「Where-Object」コマンドです。正規表現のサポートは少し変わっていることに注意してください。サポートされている文字が左側にあるPDFリファレンスカードをこちらで見つけました。
[編集]
「@JohannesRössel」で述べたように、最後の2行を1行に減らすこともできます。
((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
主な違いは、ヨハネスの方法はオブジェクトフィルタリングを行い、私の方法はテキストフィルタリングを行うことです。Powershellを使用する場合、ほとんどの場合、オブジェクトを使用する方が適切です。
[編集2]
@smoknheapが述べたように、上記のスクリプトはフォルダー構造を平坦化し、すべてのファイルを1つのフォルダーに入れます。フォルダ構造を保持するスイッチがあるかどうかはわかりません。-Recurseスイッチを試しましたが、役に立ちません。これを機能させる唯一の方法は、文字列操作に戻り、フィルターにフォルダーを追加することです。
$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
}
これを行うにはよりエレガントな方法があると確信していますが、私のテストからはうまくいきます。すべてを収集し、名前の一致とフォルダオブジェクトの両方をフィルタリングします。文字列操作にアクセスするには、ToString()メソッドを使用する必要がありました。
[編集3]
次に、パスを報告して、すべてが正しいことを確認する場合は、「Write-Host」コマンドを使用できます。何が起こっているかについてのヒントを与えるコードは次のとおりです。
cls
$source = "C:\test"
$destination = "C:\test2"
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"
$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
Write-Host "
----
Obj: $item
Path: "$item.fullname"
Destination: "$item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
}
これにより、関連する文字列が返されます。どこにも何もない場合は、どのアイテムに問題があるかがわかります。
お役に立てれば