How to import from csv only rows that don't exist

This topic contains 6 replies, has 5 voices, and was last updated by Profile photo of Balázs Ludányi Balázs Ludányi 4 months, 2 weeks ago.

  • Author
    Posts
  • #47806
    Profile photo of Peter Ščurka
    Peter Ščurka
    Participant

    Hello scripting guys,
    I would need an advise. I have csv with following collumns
    Name;Letter
    XYZ;A
    ABC;B
    FED;C

    With the following script I create folders that I need.

    $folder = "D:\Test\"
    $file = Import-Csv 'D:\Test\Test.csv' -Delimiter ';' 
    $file | %{
     $path2 = Join-Path $folder $_.Letter;
     $path3 = Join-Path $path2 $_.Name;
     $path4 = Test-Path $path3
    }
    
    $file | 
     % {    
            If ($path4 -eq $false) 
            {  
            $path = Join-Path $folder $_.Letter; 
            New-Item -Path $path -Name $_.Name -Type Directory
            }            
    } 
    

    The script works well when there is no folder or if all folders exist. The issue is when e.g folder XYZ exists and other not. The script is trying to create it again and I get error message the folder already exists. What is wrong there? What should I change to make it work correctly?
    Thanks

  • #47810
    Profile photo of Craig Duff
    Craig Duff
    Participant

    You are running the contents of $file thru two different loops, they need to be combined.

    The first loop ends with $path4 being set to True of False based on whether D:\Test\C\FED exists. That $path4 persists throughout the second loop. If all folders already exist, then D:\Test\C\FED exists and it appears to work correctly. If no folders exist, and $path4 holds False, so it creates all the folders, so it appears to work.

    • This reply was modified 4 months, 2 weeks ago by Profile photo of Craig Duff Craig Duff.
  • #47813
    Profile photo of Trevor Freedland
    Trevor Freedland
    Participant

    Maybe add another Test-Path for $path before trying to create it?

    If ($path4 -eq $false)
    {
        $path = Join-Path $folder $_.Letter;
        $exists = Test-Path -Path $path
        if ($exists -eq $false)
        {
            New-Item -Path $path -Name $_.Name -ItemType Directory
        }
    }  
    
  • #47815
    Profile photo of random commandline
    random commandline
    Participant

    If a folder does not exits, you want to create.

    Import-Csv 'D:\Test\Test.csv' -Delimiter ';' | 
    ForEach-Object {
    $newpath = Join-Path "D:\test\$($_.Letter)" $_.Name
    If (!(Test-Path $newpath)){
    New-Item -ItemType directory -Path $newpath -ErrorAction SilentlyContinue}
    }
    
  • #47817
    Profile photo of Peter Ščurka
    Peter Ščurka
    Participant

    I will test guys and let you know

    • #47834
      Profile photo of Peter Ščurka
      Peter Ščurka
      Participant

      Your code works great! Thank you!

      Import-Csv 'D:\Test\Test.csv' -Delimiter ';' | 
      ForEach-Object {
      $newpath = Join-Path "D:\test\$($_.Letter)" $_.Name
      If (!(Test-Path $newpath)){
      New-Item -ItemType directory -Path $newpath -ErrorAction SilentlyContinue}
      }
      
  • #47847
    Profile photo of Balázs Ludányi
    Balázs Ludányi
    Participant

    Could as well just write this:

    Import-CSV 'd:\test\test.csv' -d ';' | % {mkdir "d:\test\$($_.letter)\$($_.Name)" -ea:SilentlyContinue}
    

    Join-Path looks cool, but since the path is a string, you can just chain them together like that,
    and you don't need to store it in a variable, just pass it directly to mkdir (short for make directory).
    If the directory already exists, it won't create it again anyway, so no need for Test-Path,
    just suppress the error message if you don't want to see it.

You must be logged in to reply to this topic.