web-dev-qa-db-ja.com

ファイル拡張子のないファイル名のみのリストをエクスポートし、ディレクトリごとに個別のテキストファイルに出力するPowerShellスクリプト

ファイル拡張子のないファイル名のリストをエクスポートして、サブフォルダーごとにテキストファイルに出力するPowerShellスクリプトが必要です。スクリプトで親ディレクトリを指定する必要があります。その後、PowerShellは、サブフォルダーの名前をテキストファイル名(スペースと小文字なし)を使用して、サブフォルダーごとに個別のテキストファイルを作成する必要があります。次に、作成された各サブフォルダーベースのテキストファイルに、各サブフォルダーに含まれるファイル拡張子のないファイル名のリストを含めます。

$files = Get-ChildItem -Path "M:\Music" -Recurse `
| Where-Object {`
    $_.DirectoryName -notlike "*Other\Children" -and `
    $_.DirectoryName -notlike "*Other\Numbers" -and `
    $_.Extension -eq ".mp3"}
#Now loop through all the subfolders
$folder = $files.PSisContainer
ForEach ($Folder in $files)
{
$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[@($ParentS.Length - 2)]
Select-Object BaseName > C:\Users\me\Documents\$parent.txt
}

OK、これにもう少し時間を費やしました。スクリプトは、前の試行の下に追加されています。今回は非常に近いようですが、最後にテキストファイルへの書き込みが100%ではなく、以前にOut-Fileを使用していたため、各テキストファイルの下部に不要な空白行が残っていました。 [system.io.file] :: WriteAllTextと[system.io.file] :: AppendAllTextに切り替えたのはなぜですか。ただし、これらにはそれぞれ、必要なことを実行しない特異性があります。テキストファイルで、空白行のない1つの列にファイルのリストが必要です。

$files = Get-ChildItem -Path "M:\Music" -Recurse `
| Where-Object {`
    $_.DirectoryName -notlike "*Other\Children" -and `
    $_.DirectoryName -notlike "*Other\Numbers" -and `
    $_.Extension -eq ".mp3"}
#Now loop through all the subfolders
$folder = $files.Directory
ForEach ($Folder in $files)
{
$ParentS = ($folder.Fullname).split("\")
$ParentT = $ParentS[(@($ParentS.Length - 2))]
$Parent = $ParentT.replace(' ','')
[system.io.file]::WriteAllText("C:\Users\me\Documents\$parent.txt", $folder.BaseName,                                            [System.Text.Encoding]::Unicode)
}
7
Marc Kean

Powershellと.NETの共同作業の豊かさを誇示する良い機会です。

まず、フォルダのすべてのサブフォルダの完全な名前を取得する最も簡単な方法は、次のような行を使用することです。

$folders = (Get-ChildItem -Directory -Recurse M:\Music).FullName

-Directoryは、返される内容をDirectoryInfoオブジェクトの配列に制限します。 Fullshellプロパティのみを返すPowershellの機能を利用することで、フォルダーパスの配列をすべて1つのステートメントで返すことができます。

コードを数行追加するだけで、ディレクトリ内の曲をリストしたファイルを作成できます。

foreach ($folder in $folders)
{
    $fileBaseNames = (Get-ChildItem $folder\*.mp3).FullName | % {[System.IO.Path]::GetFileNameWithoutExtension($_)}
    $catalogFileName = (Split-Path $folder -Leaf) -replace ' ',''
    if ($fileBaseNames)  {Set-Content -Path $folder\$catalogFileName.txt -Value $fileBaseNames}
}

各サブフォルダーにアクセスし、すべてのサブフォルダーについて次のようにします。

  • 現在のディレクトリにあるmp3ファイル名の配列(ファイル拡張子なし)を取得します。 (私はこのような時に.NETのGetFileNameWithoutExtensionメソッドが大好きです。
  • 現在のフォルダー名(Split-Path -Leaf)を分離し、各スペースを空の文字列に置き換えることですべてのスペースを削除して、カタログのファイル名を作成します。
  • 最後に、曲のリストが空でない場合は、何でもリストを保存するのに最適な方法であるSet-Contentで保存します。

Powershellがいかに強力で簡潔であるかに驚かされることは決してありません。 $ fileBaseNamesを作成する行は、一部の人にとって少しぎこちないかもしれませんが、foreach-objectコンストラクトを簡単に準備できる複数行のforeach句に変換するのは簡単です。

17
WiiBopp