PDA

Показать полную графическую версию : Создание .bat файла для выборки строк из .csv файла в .xlsx


GODolubOFF
10-12-2015, 14:07
Суть такова. Есть 6 csv файлов с разными именами, в них по 4 столбца. В первом столбце мак хэш сетевого устройства, во втором дата и время (чч.мм.гггг чч:мм), в третьем уровень сигнала (-25 например), в четвертом название устройства.
Необходим скрипт (он будет в папке с csv файлами), при запуске которого в csv файле с именем "C46E1F5A5DD4" во втором столбце будут искаться ячейки где перерыв во времени составляет больше 5 минут.
Выглядит этот столбец так:
61C5CDFAF15E602BA6FBF558497AD741 09.12.2015 11:35 -53 nokia
8F5B5E1AFE81B77705310942D9A5ED15 09.12.2015 11:35 -75 samsung
DC34B0E1B18874CE58AA9C81FB468340 09.12.2015 11:35 -69 samsung
D4F0561F459F304F7BB77E42F7C2F096 09.12.2015 11:35 -69 samsung
D2D6DB4EF7C69060CA87934F930E23BA 09.12.2015 11:35 -80 samsung
0E3E3642F5275969DBDE043823F95B30 09.12.2015 11:43 -52
A10AE2D6CD32B0CAD6505E29ABADCB18 09.12.2015 11:43 -75 local
DD9AF3BB214ED6AD3301956BAFB0AB74 09.12.2015 11:43 -72 apple
Жирным текстом выделены строки перерыв между которыми составляет больше 5 минут.
Нужно чтобы скрипт нашел все эти строки в файле csv, для него создал xlsx файл и вогнал обе эти строки в этот xlsx файл.
Всего строк в этих файлах по 40-50 тысяч, визуально все строки просмотреть и вычислить где-же интервал составляет более 5 минут - очень тяжко.
Глаза буквально вываливаются из орбит.
Помогите пожалуйста, очень вас я прошу.

c4uran
10-12-2015, 14:38
создал xlsx файл

cmd так не может

средствами экзеля делается не сложно вроде(создается таблица и поля туда тянуться с условиями из других файлов)

Foreigner
10-12-2015, 15:02
GODolubOFF, С помощью PowerShell (это быстрей, чем вручную):

$csv = (get-content C46E1F5A5DD4.csv) -replace '(\s)+','$1' | foreach {

[pscustomobject] @{

hesh = $_.split()[0]
date = [datetime]($_.split()[1,2] -join ' ')
freq = $_.split()[3]
brеnd = $_.split()[4]

}
}

0..($csv.length - 1) | foreach {

if ($check)
{
if (($csv[$_].date - $check).minutes -ge 5)
{
[array] $new_csv += $csv[($_-1)]
$new_csv += $csv[$_]
$check = $null
}
}

else { $check = $csv[$_].date }

}

$new_csv | convertto-csv -notypeinfo | out-file new.csv

А потом new.csv уже открыть в Excel (здесь я не уверен, за отсутствием офиса)

Iska
10-12-2015, 15:40
А потом new.csv уже открыть в Excel (здесь я не уверен, за отсутствием офиса) »
В 2003-м, по крайней мере, откроется, .csv ассоциируется именно с Microsoft Excel. Впрочем, на PoSH можно и xls сделать посредством Automation.

GODolubOFF
10-12-2015, 17:14
$csv = (get-content C46E1F5A5DD4.csv) -replace '(\s)+','$1' | foreach {
[pscustomobject] @{
hesh = $_.split()[0]
date = [datetime]($_.split()[1,2] -join ' ')
freq = $_.split()[3]
brеnd = $_.split()[4]
}
}
0..($csv.length - 1) | foreach {
if ($check)
{
if (($csv[$_].date - $check).minutes -ge 5)
{
[array] $new_csv += $csv[($_-1)]
$new_csv += $csv[$_]
$check = $null
}
}
else { $check = $csv[$_].date }
}
$new_csv | convertto-csv -notypeinfo | out-file new.csv »

Вогнал я код в Powershell - ругается.

PS C:\Users\Aleksandr> $csv = (get-content C46E1F07AF88.csv) -replace '(\s)+','$1' | foreach {
>>
>> [pscustomobject] @{
>>
>> hesh = $_.split()[0]
>> date = [datetime]($_.split()[1,2] -join ' ')
>> freq = $_.split()[3]
>> brеnd = $_.split()[4]
>>
>> }
>> }
>>
Не удается преобразовать значение "7:52:46;-65;" в тип "System.DateTime". Ошибка: "Строка не распознана как действитель
ное значение DateTime."
строка:2 знак:1
+ [pscustomobject] @{
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider

Foreigner
10-12-2015, 17:37
7:52:46;-65; »
В вашем примере нет разделителей ';'. Поэтому и ошибка. Выложите пример файла, только закройте его в тег 'code' или дайте ссылку на реальный файл (строк на 100)

GODolubOFF
10-12-2015, 17:45
В вашем примере нет разделителей ';'. Поэтому и ошибка. Выложите пример файла, только закройте его в тег 'code' или дайте ссылку на реальный файл (строк на 100) »

Ссылка на файл:
http://depositfiles.com/files/pmrnuqlx4

Foreigner
10-12-2015, 18:47
GODolubOFF, Попробуйте, я особо результат не проверял, но что-то на выходе похожее на правду получается:

$csv = import-csv -delimiter ';' -header 'Hash','DateTime','SignalLevel','Brand' C46E1F07AF88.csv
$check = [datetime] $csv[0].datetime

1..($csv.count-1) | foreach {

if (([datetime] $csv[$_].datetime - $check).minutes -ge 5)
{
[array] $new_csv += $csv[($_-1)]
$new_csv += $csv[$_]
$check = [datetime] $csv[$_].datetime
}

}

$new_csv | convertto-csv -notypeinfo | out-file new.csv

GODolubOFF
11-12-2015, 10:11
$csv = import-csv -delimiter ';' -header 'Hash','DateTime','SignalLevel','Brand' C46E1F07AF88.csv
$check = [datetime] $csv[0].datetime
1..($csv.count-1) | foreach {
if (([datetime] $csv[$_].datetime - $check).minutes -ge 5)
{
[array] $new_csv += $csv[($_-1)]
$new_csv += $csv[$_]
$check = [datetime] $csv[$_].datetime
}
}
$new_csv | convertto-csv -notypeinfo | out-file new.csv »

Всё круто, реально работает, только вот выборка идет не по минутам, а по секундам. Разница в секундах не интересует, интересует разница в минутах, а точнее те строки, где разница составляет больше 5 минут.
Вот, то что на выходе получилось:
http://depositfiles.com/files/dqeso2y2x

Foreigner
11-12-2015, 12:45
GODolubOFF, Я правильно понял, что, например 08:00:59 и 08:05:00 попадают в результирующий файл? Тогда:

$csv = import-csv -delimiter ';' -header 'Hash','DateTime','SignalLevel','Brand' C46E1F07AF88.csv
$check = [datetime] $csv[0].datetime.replace(':\d{2}$',$null)

1..($csv.count-1) | foreach {

if ((([datetime] $csv[$_].datetime.replace(':\d{2}$',$null)) - $check).minutes -gt 5)
{
[array] $new_csv += $csv[($_-1)]
$new_csv += $csv[$_]
$check = [datetime] $csv[$_].datetime.replace(':\d{2}$',$null)
}

}

$new_csv | convertto-csv -notypeinfo | out-file new.csv

Вы написали больше 5 минут, если надо больше или равно, то исправьте -gt на -ge

GODolubOFF
14-12-2015, 15:34
$csv = import-csv -delimiter ';' -header 'Hash','DateTime','SignalLevel','Brand' C46E1F07AF88.csv
$check = [datetime] $csv[0].datetime.replace(':\d{2}$',$null)
1..($csv.count-1) | foreach {
if ((([datetime] $csv[$_].datetime.replace(':\d{2}$',$null)) - $check).minutes -gt 5)
{
[array] $new_csv += $csv[($_-1)]
$new_csv += $csv[$_]
$check = [datetime] $csv[$_].datetime.replace(':\d{2}$',$null)
}
}
$new_csv | convertto-csv -notypeinfo | out-file new.csv »

Раньше времени порадовался)
Код работает, но какие-то нестыковки заметил.
Сверил 2 файла, исходный и получившийся, и как то не сходится то, что было и то, что стало.
Выскажу свои догадки.
Исходный файл csv который я прикреплял, содержит строки, для которых не включен фильтр "от старых к новым". Поэтому там время идет таким образом:
09.12.2015 9:57
09.12.2015 9:59
09.12.2015 9:57
09.12.2015 9:59
09.12.2015 9:58
09.12.2015 9:59
09.12.2015 9:59
09.12.2015 9:59
09.12.2015 9:57
09.12.2015 9:57
09.12.2015 9:59
09.12.2015 9:57
09.12.2015 10:00
09.12.2015 9:57
09.12.2015 9:57
09.12.2015 9:57
09.12.2015 10:00
09.12.2015 9:57
09.12.2015 10:00
09.12.2015 9:57
09.12.2015 10:00

Соответственно и выборка по времени некорректная получается.
Попробовал отфильтровать файл по времени, но все равно данные не сходятся.
Чтобы вы поняли о чем я говорю, прикрепляю ссылки на исходник и выходной файл.
http://depositfiles.com/files/i9d94lk6v
http://depositfiles.com/files/xniq7f06r

Попытался разобраться своими силами, но безуспешно.
Приходится вновь обращаться к вам за помощью.




© OSzone.net 2001-2012