Powershell split file name into arrary

This topic contains 18 replies, has 3 voices, and was last updated by  lalajee 2 months, 2 weeks ago.

  • Author
    Posts
  • #94872

    lalajee
    Participant

    I have a folder with list of all of the movies inside this folder in following format.

    [1979] Name of the movie [P1] – Disney
    [1979] Name of the movie [P1][Director Edition] – PTC
    [1980] Name of the movie [P8][Director Edition] – Test

    I would like to get all of the movies in that folder and go through them and put them into three different attribute Year, Name, Studio

    All this info will be save into a single file name of the movie

    This is how I wont to save the info into the file

    Name of the movie [P1]
    1979
    Disney

    or

    Name of the movie [P1][Director Edition]
    1979
    PTC

    I try to write this code

    $regex = [regex]"\[(\w+)\](\w+\[\w+\])-(\w+)"
    $name = "[TEST]TEST[TEST]-TEST"
    $tokens = $regex.Match($name).groups[1,2,3] | Select -ExpandProperty Value

    Which worked fine but when running it like this but it doesnt work when I run it in loop.

    $name = dir *.mp4 | select BaseName
    $regex = [regex]"\[(\w+)\](\w+\[\w+\])-(\w+)"
    foreach ($n in $name)
    {
    $file_name = $n.BaseName.ToString();
    $year, $title, $studio = $regex.Match($file_name).groups[1,2,3] | Select -ExpandProperty Value
    }

  • #94875

    Olaf Soyk
    Participant

    When you remove the "| select BaseName" it should run as expected I think.

    • #94876

      lalajee
      Participant

      it doesnt work. you can test the code on your PC.

  • #94882

    Olaf Soyk
    Participant

    OK, then we try it my way ... 😉 😀

    $Path = 'C:\sample\movies'
    $Pattern = '\[(\w+)\]\s*(((\w+)\s*)*)\[(\w+)\](\[(.*)\])*.*?(\w+)$'
    Get-ChildItem -Path $Path -Filter *.mp4 |
        ForEach-Object {
            $_.BaseName -match $Pattern | Out-Null
            [PSCustomObject][ordered]@{
                Year = $Matches[1]
                Title = $Matches[2]
                Studio = $Matches[8]
                Edition = $Matches[7]
                Something = $Matches[5]
            }
        } |
            Format-Table -AutoSize
    
  • #94885

    js
    Participant

    Could this be another opportunity for ConvertFrom-String??

    $template = @'                                                                                       
    [{Year*:1979}] {Name:Name of the movie [P1]} - {Studio:Disney}                                       
    [{Year*:1979}] {Name:Name of the movie [P1][Director Edition]} - {Studio:PTC}                        
    [{Year*:1980}] {Name:Name of the movie [P8][Director Edition]} - {Studio:Test}                       
    '@
    
    $testText = @'                                                                                       
    [1979] Name of the movie [P1] - Disney                                                               
    [1979] Name of the movie [P1][Director Edition] - PTC                                                
    [1980] Name of the movie [P8][Director Edition] - Test                                               
    '@
    
    PS C:\Users\me> $testText | ConvertFrom-String -TemplateContent $template
    
    Year Name                                     Studio
    ---- ----                                     ------
    1979 Name of the movie [P1]                   Disney
    1979 Name of the movie [P1][Director Edition] PTC
    1980 Name of the movie [P8][Director Edition] Test
    
    • #94888

      Olaf Soyk
      Participant

      @js – wow – cool idea – and it's even easier to read – thanks.

    • #94890

      lalajee
      Participant

      Hi, Thank you for your reply but it doesn't work.

      It should work with any movie, I just gave a example of how the name of each movie is setup

    • #94905

      js
      Participant

      You can do the same thing I did but put in real examples.

  • #94891

    lalajee
    Participant

    I only want to split the movie name into three parts.

    1st year
    2nd Name
    3rd Studio

  • #94893

    Olaf Soyk
    Participant

    ... reply but it doesn't work.

    hmmm ... could you please be more precise? What exaclty does not work? Does it work at least with the examples you gave?

  • #94896

    lalajee
    Participant

    I have folder with all of the movies. Which i like to split in three parts.

    This is how Text file should look like
    Year: 1979
    Name: Name of the movie [P1]
    Studio: Disney

    Any thing in first [] will be 1st part of the file, any thing after this until – will be 2nd part of the file and anything after – will be 3rd part of the file.

    • #94897

      Olaf Soyk
      Participant

      Did you try to understand and maybe to modify the code to your needs?

      $Path = 'C:\sample\movies'
      $Pattern = '\[(\w+)\]\s*(((\w+)\s*)*)\[(\w+)\](\[(.*)\])*.*?(\w+)$'
      Get-ChildItem -Path $Path -Filter *.mp4 |
          ForEach-Object {
              $_.BaseName -match $Pattern | Out-Null
              [PSCustomObject][ordered]@{
                  Year = $Matches[1]
                  Title = $Matches[2] + ' ' + $Matches[5] + ' ' + $Matches[7]
                  Studio = $Matches[8]
              }
          }
  • #94900

    lalajee
    Participant

    I just try my code again and its work but because I have space in my movies name it doesnt work. i think I need to make changes to $regex = [regex]"\[(\w+)\](\w+\[\w+\])-(\w+)"

    • #94903

      Olaf Soyk
      Participant

      I spend a little effort to try to help you. So could you please at least try the code I posted and tell me if it works? And if it does not work, tell what does not work.

    • #95049

      lalajee
      Participant

      Hi Olaf,

      Thank you for your replay.

      I did try your code which works on some movies but not all.

      lets say I have movie which is name in this way [1979] Name of the movie [P1][Director Edition] [Somthing here] 1979] Name of the movie [P1][Director Edition] then something more – PTC

      What your code does is that it puts each brackets into new array which i dont wont, I just wont to split the name into three values

      like this

      1979
      Name of the movie [P1][Director Edition] [Somthing here] 1979] Name of the movie [P1][Director Edition] then something more
      PTC

    • #95050

      Olaf Soyk
      Participant

      lalajee,

      hmmm .... you gave three example file names and I'm almost sure about that – for these three example file names my code worked as intended, right?
      String manipulation is always error prone if you don't have enough information about the possible patterns in the source strings.
      Actually I wanted to give you some extra goodies and split your file names in (for me) logical pieces like a database would have. Each single piece of information is stored in single cell. But therefore the source data would have to have a certain structure as well.
      The new file name pattern you gave looks weird for me. Just like something went wrong in an earlier naming step of some other script.
      But anyway, I don't like to give up. So here is another try for the example file names you gave:

      $Path = 'D:\sample'
      $Pattern = '^\[(\w+)\]\s+(.*)\s(\–|\−|\–|\—)\s(.*)$'
      Get-ChildItem -Path $Path -Filter *.mp4 |
          ForEach-Object {
              $_.BaseName -match $Pattern | Out-Null
              [PSCustomObject][ordered]@{
                  Year = $Matches[1]
                  Title = $Matches[2]
                  Studio = $Matches[4]
              }
          }

      BTW: I had some problems recognizing what dash, minus, hyphen or whatever you use in your file names. So I included 4 of them in the pattern and hope one of them fits. If not – you have to do some research for it.

  • #95151

    lalajee
    Participant

    Thank you for all your help. Finally I got it

    $Path = 'D:\Training\Test'
    $regex = "\[([\w|\s]+)\]([\w|\s]+\[[\w|\s]+\].*)\s*-\s*([\w|,|\s]+)"
    Get-ChildItem -Path $Path -Filter *.txt |
        ForEach-Object {
            $name = $_.BaseName
            $groups = [regex]::Match($name, $regex).Captures.Groups
            #$groups[0].Value
            $groups[1].Value
            $groups[2].Value.Trim()
            $groups[3].Value
            Write-Host
        }
    • #95154

      Olaf Soyk
      Participant

      This code works? Really? If I try it with the example file names you posted it does not work at all. I get a lot of errors.
      And regardless of that – do you ever answer questions? :-/

    • #95163

      lalajee
      Participant

      Hi Olaf,

      Because you are copying file name from this site it add -(Dash) which code doesnt like.

      PS C:\Users\User> $Path = 'D:\Training\Test'
      $regex = "\[([\w|\s]+)\]([\w|\s]+\[[\w|\s]+\].*)\s*-\s*([\w|,|\s]+)"
      Get-ChildItem -Path $Path -Filter *.txt |
          ForEach-Object {
              $name = $_.BaseName -replace '–', '-'
              $groups = [regex]::Match($name, $regex).Captures.Groups
              $groups[1].Value
              $groups[2].Value.Trim()
              $groups[3].Value
              Write-Host
          }
      1979
      Name of the movie [P1]
      Disney
      
      1979
      Name of the movie [P1][Director Edition]
      PTC
      
      1980
      Name of the movie [P8][Director Edition]
      Test

      I update code to repalce this with normal dash

You must be logged in to reply to this topic.