@Sunvortex

Как отредактировать csv файл с помощью powershell?

Добрый день!
Подскажите, как добавить новый столбец в csv файл с данными полученными из другого столбца?
Есть файл с полными путями к файлам, их временем создания и тд, нужно добавить столбец в котором будет указан новый путь по которому этот файл нужно переместить.
"FullName";"CreationTime";"LastAccessTime";"LastWriteTime";"Length";"Extension"
"\\?\D:\11111\22222\333\44444\filename.ext";"date:time";"date:time";"date:time";"size";".ext"

В новом столбце нужно получить новый путь \\?\D:\11111\to_move\22222\333\44444\
В исходном файле более 2кк строк, поэтому отредактировать через excel не получается.

Пока пользуюсь вот таким скриптом, который создает новый файл, но на файлах с огромным количеством строк процесс очень долгий
$Paths = Import-Csv -Path "C:\temp\OldFiles.csv" -Delimiter ';'
$Paths = $Paths.FullName
$ToMove = "C:\temp\ToMove.csv"
$dataColl = @()
foreach  ($Path in $Paths){
foreach  ( $Newpath in $Path){
    If ($Path.Substring(0,2) -eq "\\")  {$Newpath = ("\\?\D:\11111\To_Move" + $Path.Remove(0,12))}
    $Destpath = Split-Path $Newpath -Parent
    $dataObject = New-Object PSObject
    Add-Member -InputObject $dataObject -MemberType NoteProperty -Name "FullName" -Value $Path
    Add-Member -InputObject $dataObject -MemberType NoteProperty -Name "NewPath" -Value $Destpath
    $dataColl += $dataObject
    }
    }
$dataColl | Export-Csv -Force -Path $ToMove -Encoding UTF8 -Delimiter ";" -NoTypeInformation -Append
  • Вопрос задан
  • 300 просмотров
Решения вопроса 1
@NortheR73
системный инженер
Думается мне, что как-то так должно быть:
$Paths = Import-Csv -Path "C:\temp\OldFiles.csv" -Delimiter ';'
$ToMove = "C:\temp\ToMove.csv"
foreach  ($Row in $Paths)
{
    $Path = $Row.FullName
    If ($Path.Substring(0,2) -eq "\\")  {$Newpath = ("\\?\D:\11111\To_Move" + $Path.Remove(0,12))}
    $Destpath = Split-Path $Newpath -Parent
    $Row | Add-Member -NotePropertyName "NewPath" -NotePropertyValue $DestPath
}
$Paths | Export-Csv -Force -Path $ToMove -Encoding UTF8 -Delimiter ";" -NoTypeInformation
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@MaxKozlov Куратор тега PowerShell
Стоит проверить что именно у вас долгое
Import-csv вы никак не ускорите.
А вот $dataColl - реальный кандидат на ускорение
Проще всего использовать ArrayList вместо массива
...
$dataColl = New-Object System.Collections.ArrayList
foreach  ($Path in $Paths){
....
    [void]$dataColl.Add($dataObject)
  }
}
...


И вообще, массивы для коллекционирования более 1000 элементов - тормоза, потому что они каждый раз пересоздаются и копируются из старого в новый.

Measure-Command { $a = @(); 1..1000 | %{ $a += $_ } }

    TotalMilliseconds : 40,3721

Measure-Command { $a = New-Object System.Collections.ArrayList; 1..1000 | %{ [void]$a.Add($_) } }

    TotalMilliseconds : 18,5863

# А для 10000 уже
   TotalMilliseconds : 2016,3737
  vs
   TotalMilliseconds : 57,6177


p.s. Кстати да, Роман Безруков верно заметил, что новый массив создавать вообще не обязательно. Но информация выше сильно влияет на работу, так что оставлю :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы