Note: I’m a beginner to Powershell and a bit more familiar with Bash (though still a beginner for that too).

*I have multiple PDF files and I want to rename each file based on a list of names found in an Excel/CSV (could be a text file if easier) file.

*The list begins at the A2 cell and the A1 cell has the header ‘name’.

*The files are in sequential order and match the order of the list of names.

Thanks for your help!

  • badlotus
    link
    fedilink
    arrow-up
    3
    ·
    7 months ago

    Are you only interested in using Powershell? There’s a FOSS utility called PowerRename (part of PowerToys) which uses find/replace and RegEx to let you batch rename a group of files: MS Learn - PowerRename

  • Gurfaild@feddit.de
    link
    fedilink
    arrow-up
    3
    ·
    edit-2
    7 months ago

    If the CSV file contains both the current names and the new names, this should work if you use the first line for column labels (I’m using OldName and NewName in this example):

    Import-CSV $pathToCSV | ForEach-Object { Rename-Item $_.OldName $_.NewName }

    If you just have a list of new names as a text file where the first line of the file is the new name for the first file (by name, sorted alphabetically), this should work:

    $files = Get-ChildItem -File *.pdf | Sort-Object -Property Name #I think the output of Get-ChildItem is already sorted by name, but I'm not sure
    $newNames = Get-Content $pathToTXT
    if ($files.Count -ne $newNames.Count) {
        Write-Error "The number of PDF files to be renamed does not match the number of new names"
        exit
    }
    0..($files.Count - 1) | ForEach-Object { Rename-Item $files[$_] $newNames[$_] }
    
    
    • BobTheDestroyer@lemy.lolOP
      link
      fedilink
      arrow-up
      1
      ·
      7 months ago

      Thanks but PS closes so I assume it ran into an error. I’m not sure why because there is the same number of files and list items. I doublechecked to make sure.

      • Gurfaild@feddit.de
        link
        fedilink
        arrow-up
        1
        ·
        edit-2
        7 months ago

        I have no idea why this wouldn’t work on your machine - I’ve tested it on mine and it works fine. So maybe you have overlooked some small things:

        • If there are any other PDFs in the directory that you don’t want to rename, then the list of files is longer than the list of names.

        • If the PS window closes completely, you might have typed it into the terminal instead of running it as a script - then the problem might just be that you closed the if block too early, so PS immediately executes the exit command.

        • If your list of new names contains a column label like in a one-column CSV, then it has one more line than there are files.

    • BobTheDestroyer@lemy.lolOP
      link
      fedilink
      arrow-up
      1
      ·
      7 months ago

      Perhaps my directions were unclear. The Excel/CSV file has the new names and I want to use them to replace the default names for the PDF files.

      • d3Xt3r@lemmy.nz
        link
        fedilink
        arrow-up
        3
        ·
        edit-2
        7 months ago

        There’s no point in having a CSV for just a single column, just make it a simple text file and it’ll simplify the code a bit. So assuming you have a file called names.txt, here’s a one-liner that can do the trick:

        $names = cat "\path\to\names.txt"; $i=0; dir | % { ren $_ "$($names[$i])"; $i++ }
        

        As long as the order in your text file matches the order shown by dir, you shouldn’t have any issues. Maybe do a dry run with a -WhatIf to the ren first to see how the files are being renamed, before you do the actual rename. :)

        • BobTheDestroyer@lemy.lolOP
          link
          fedilink
          arrow-up
          1
          ·
          7 months ago

          Also I had someone help with a similar task of duplicating a Word file that is renamed from a list of names found in a csv file. What would be the code when a txt file is used?

          Import-csv ‘.\individuals.csv’ | foreach-object {
              $newname = ‘2’ + $_.name + '.docx’
              Copy-item '.\_2023 Summary Page.docx' $newname
          }
          
        • BobTheDestroyer@lemy.lolOP
          link
          fedilink
          arrow-up
          1
          ·
          7 months ago

          Thanks but I’m getting a ‘Cannot create a file when that file already exists.’ error. I checked the path so I am certain it is correct.

          • d3Xt3r@lemmy.nz
            link
            fedilink
            arrow-up
            2
            ·
            7 months ago

            That means there’s a duplicate entry, check the full error message for the file name. You can also use the -Verbose switch to see what’s going on.

              • d3Xt3r@lemmy.nz
                link
                fedilink
                arrow-up
                2
                ·
                7 months ago

                Ah, I misplaced a quote in my code, I’ve update the post - try version.

                • BobTheDestroyer@lemy.lolOP
                  link
                  fedilink
                  arrow-up
                  1
                  ·
                  edit-2
                  7 months ago

                  So it sort of worked in that it outputed a bunch of files with the names but with blank icons and not the Adobe icons. Powershell also had an error for each list item that looked like the following:

                  Rename-Item : Cannot bind argument to parameter 'NewName' because it is an empty string.
                  At line:1 char:86
                  + ... ads\individuals.txt"; $i=0; dir | % { ren $_ "$($names[$i])"; $i++ }
                  +                                                   ~~~~~~~~~~~~~~~
                      + CategoryInfo          : InvalidData: (:) [Rename-Item], ParameterBindingValidationException
                      + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.Rena
                     meItemCommand
                  

                  Maybe the command needs ‘.pdf’ somewhere?