![]() |
объединить данные из папок в один csv
У меня много файлов csv, которые находятся в разных папках. пример
"C:\Users\Admin\Downloads\28-09-2018_17-39-27\data\23842735206960137\files in csv" next "C:\Users\Admin\Downloads\28-09-2018_17-39-27\data\23842735207380137\files in csv" В каждой папке примерно 30-35 файлов мне нужно объединить их в один csv Также, в каждой папке, например 23842735206960137 23842735207380137 не обязательно работать со всеми 34 файлами. Чтобы объединиться в один набор данных из каждой папки, мне нужно взять только один файл, который занимает больше места. Чтобы быть более понятным в папке 23842735206960137 такие файлы 1.csv (1kb) 2.csv(1kb) 3.csv(1kb) 4.csv(4kb) 5.csv(4kb) 6.csv(4kb) 7.csv(4kb) ВСЕГДА другие файлы имеют тот же размер и тот же контент, который имеет csv с максимальным размером. Т.Е. Итак, как только мы достигнем первого файла с максимальным размером, все остальные файлы имеют одинаковый размер и содержат одну и ту же информацию, что и самый первый с макс размером. Поэтому мы берем только первый файл с максимальным размером из каждой папки, а затем объединяем эти файлы в один набор данных. Как это сделать в Powershell? |
kontox, Вы ж не первый день на форуме — есть ряд вопросов, влияющих на код: какова кодировка файлов, есть ли BOM, если это юникод, какие концы строк, есть ли заголовки в файлах и т.д.
Упакуйте пару-тройку таких папок с файлами в один архив и выложите его на DropMeFiles.com. |
Iska, есть системные умолчания, можно и нужно исходить из них. А прибивать к коду гвоздями чужеродные концы строк уже в случае необходимости.
Цитата:
|
везде все поля одинаковые.
|
kontox, попробуйте так:
Скрытый текст
Код:
$sRootFolder = 'C:\Мои проекты\0203' |
Цитата:
Код:
# Корневой каталог |
Однострочник:
Код:
Get-ChildItem ./ -Recurse -File -Filter "*.csv" | Group-Object -Property PSParentPath | % { $max = @{ value = 0; object = $null }; $_.Group | % { if ($max.value -le $_.length) { $max.value=$_.value; $max.object=$_ }}; $max.object } | % {Import-Csv $_.FullName -Delimiter ';' } | Export-Csv -NoTypeInformation -Delimiter ';' ..\all.csv Куда складывать - путь к файлу в самом конце (если итоговой файл попытаться положить внутри директорий для поиска - будет плохо) |
Цитата:
|
Iska, это сквозной pipeline - результирующий файл создаётся когда ещё не все директории прочитаны
|
Busla, спасибо, ясно, такой фокус не сработает.
|
Вложений: 1
Iska, подскажите, я пытаюсь использовать ваше решение, но выходит ошибка.
скрин |
kontox, похоже, у вас старая версия powershell
какая ОС? по идее, этот код надо класть в файл с расширением ps1 и запускать как скрипт |
Busla, windows 7 x32
я с расширением ps1 и делал. Busla, проверил, Вы правы. Дело в версии PS. Код от Iska шикарно отработал. |
Iska, Busla, а можно вас попросить усложнить код ps.
$sRootFolder = 'C:\Мои проекты\0203' допусти проектов 10 $sRootFolder = 'C:\Мои проекты\0204' $sRootFolder = 'C:\Мои проекты\0205' $sRootFolder = 'C:\Мои проекты\0206' ... Как сделать чтобы для всех этих папок создавались файлы csv(в каждой отдельно соответственно). Потому что Каждый проект отдельная аналитика а то для каждый папки придется создать 10 ps файлов)) |
kontox, не надо создавать 10 файлов проектов. Можно задать получение «корневого» каталога параметром скрипта и десять раз вызвать его из пакетного файла, передав одному и тому же скрипту, соответственно, десять разных аргументов. Можно просто оформить текущее содержимое отдельной функцией, где параметром функции будет «корневой» каталог и вызывать её десять раз, передавая ей каждый раз другой аргумент.
Или тупо, по рабоче-крестьянски, просто перечислить, або массивом, в том же самом коде, например: Скрытый текст
Код:
$aRootFolders = @('C:\Мои проекты\0203', 'C:\MyProjects\0002', 'C:\Мои проекты\0206', 'C:\Мои проекты\0207', 'C:\MyProjects\0003') |
Iska, из-за своей невнимательность я оплошал и ещё как. Дело в том, что я думал, что все файлы, у который идет одинаковый размер , они содержат одинаковые данные
1.csv (1kb) 2.csv(1kb) 3.csv(1kb) 4.csv(4kb) 5.csv(4kb) 6.csv(4kb) 7.csv(4kb) » На деле, после ручного анализа они имеют одинаковый размер, но данные разные там, не колонки, а именно их значения Можно ли скрипт переделать, чтобы он просто все csv объединял в один. без учета размера. |
То есть, все *.csv из всех подкаталогов первого уровня очередного «корневого» каталога объединяются в один, я правильно понимаю?
Попробуйте так: Скрытый текст
Код:
$aRootFolders = @('C:\Мои проекты\0203', 'C:\MyProjects\0002', 'C:\Мои проекты\0206', 'C:\Мои проекты\0207', 'C:\MyProjects\0003') |
Цитата:
Код:
# Корневой каталог |
Вложений: 1
Друзья, подскажите, вот код
вот код $aRootFolders = @('C:\Intel\Game_4', 'C:\Intel\Game_5') foreach($sRootFolder in $aRootFolders) { if([System.IO.Directory]::Exists($sRootFolder)) { Write-Host "[$sRootFolder]" -ForegroundColor Yellow $aContent = @() Get-ChildItem -Path $sRootFolder -Directory -Depth 1 |` ForEach-Object -Process { Write-Host " [$($_.Name)]" -ForegroundColor Green Get-ChildItem -Path "$($_.FullName)\*.*" -File -Include "*.csv" |` ForEach-Object -Process { Write-Host " --> $($_.Name)" -ForegroundColor Cyan $aCurrContent = [System.IO.File]::ReadAllLines($_.FullName) if($aContent.Count -eq 0) { $aContent += $aCurrContent } else { $aContent += $aCurrContent[1..$($aCurrContent.Count - 1)] } } } $sResultFileName = "$sRootFolder\$(([System.IO.DirectoryInfo]::new($sRootFolder).BaseName)).csv" Write-Host "<-- $sResultFileName`r`n" -ForegroundColor Magenta [System.IO.File]::WriteAllText($sResultFileName, [System.String]::Join("`n", $aContent))#> } else { Write-Host "Can't find root folder [$sRootFolder]." -ForegroundColor Red } } как сделать, чтобы напротив строки, было указано из какой подпапки строка? пример на снике |
Время: 23:11. |
Время: 23:11.
© OSzone.net 2001-