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

This topic contains 6 replies, has 5 voices, and was last updated by  Balázs Ludányi 1 year, 2 months ago.

  • Author
    Posts
  • #47806

    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

    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 1 year, 2 months ago by  Craig Duff.
  • #47813

    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

    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

    Peter Ščurka
    Participant

    I will test guys and let you know

    • #47834

      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

    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.