PowerShell script to export a list of file names only with no file extension then output to a text file separate for each directory

67,778

What a good opportunity to show off the richness of Powershell and .NET working together.

First off, the easiest way to get the full names of all the subfolders of a folder is with a line like this:

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

-Directory limits what is returned to an array of DirectoryInfo object. By taking advantage of Powershell's ability to return only the FullName property, we can return an array of folder paths all in one statement

We can create the files listing the songs in the directory with just a few more lines of code:

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}
}

We visit each subfolder and for every subfolder we:

  • Get an array of the mp3 file names (without file extension) in the current directory. (I love .NET's GetFileNameWithoutExtension method at times like this.
  • Create the file name for our catalog by isolating the current folder name (Split-Path -Leaf) and sucking out all the spaces by replacing each space with an empty string.
  • Finally if our list of songs isn't empty we save it off with Set-Content, a great way to save a list of anything.

It never ceases to amaze me how powerfull and concise Powershell is. The line creating the $fileBaseNames may be a little gnarly for some, but it would be an easy enough thing to turn the foreach-object construct into an easy to ready multiline foreach clause.

Share:
67,778
Marc Kean
Author by

Marc Kean

Updated on July 05, 2022

Comments

  • Marc Kean
    Marc Kean almost 2 years

    I need a PowerShell script to export a list of file names only with no file extension then output to a text file separate for each sub-folder. I need to specify a parent directory in the script, then PowerShell needs to go off and create a separate text file for each sub folder using the the name of the sub folder for the text file name (with no spaces and lowercase). Then in each sub-folder based text file created, have a list of file names that are contained in each sub-folder with no file extension.

    $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, spent some more time on this, script is added below to the previous attempt. Seems I am very close this time, however writing to the text file at the end is not 100%, I was using Out-File before which was leaving a blank line at the bottom of each text file which I didn't want. Why I switched to [system.io.file]::WriteAllText and [system.io.file]::AppendAllText, however each of these have their idiosyncrasies which don't do what I need. In the Text file I need the list of files in one column with no blank lines.

    $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)
    }
    
  • TessellatingHeckler
    TessellatingHeckler almost 10 years
    You can do $fileBaseNames = (Get-ChildItem $folder\*.mp3).BaseName to directly get the filenames sans extension.
  • TessellatingHeckler
    TessellatingHeckler almost 10 years
    Or maybe (gci -File) | % {$_.Name.TrimEnd($_.Extension)}
  • Marc Kean
    Marc Kean almost 10 years
    Hey WiiBopp, thanks for your valuable input, however the text files created still have a blank line at the end. I am trying to create text files with no blank lines at the end, so the text file will list all songs, with the last song being the absolute last line of the text file.