Показать полную графическую версию : Обработка файла с помощью AutoIT
Space-06
28-06-2011, 11:06
Доброго времени суток уважаемые!!!
не подскажете как удобнее всего реализовать следующее:
есть файл csv в котором есть данные разделенные запятыми. Так вот мне необходимо суммировать некоторые данные по строкам.
приведу пример исходного файла:
07.06.2011 8:01 62.80.230.41 ХХХ.ХХХ.ХХХ.ХХХ TCP 3389 1875 0,022325 10
07.06.2011 8:01 81.23.3.110 ХХХ.ХХХ.ХХХ.ХХХ TCP 3389 1987 0,022293 10
так вот хотелось бы в итоге получить итоговый файл в котором отображалось бы сумма столбца 8 соответствующая 3 столбцу
т.е. простыми словами суммировать по строкам. Трудность в том что в файле около 230 000 строк - и использовать эксель с макросами немного затруднительно.
madmasles
28-06-2011, 11:30
Space-06,
Т.е. сумма (0,022325 и т.п.) должна быть подсчитана отдельно для всех вхождений 62.80.230.41, потом для всех 81.23.3.110, ..., и.т.д. Я правильно понял?
Space-06, быстрее всего (для счёта, не для времени разработки, понятно) будет использование подобной технологии: VBScript: работа с большими текстовыми файлами (http://forum.script-coding.com/viewtopic.php?id=1322).
P.S. Вопрос, собственно, упирается в следующее: допустимо ли использование статистических функций в текстовом провайдере OLEDB?! Я сие не выяснял.
Space-06
28-06-2011, 19:14
Т.е. сумма (0,022325 и т.п.) должна быть подсчитана отдельно для всех вхождений 62.80.230.41, потом для всех 81.23.3.110, ..., и.т.д. Я правильно понял? »
да это именно так.
быстрее всего (для счёта, не для времени разработки, понятно) будет использование подобной технологии: vbscript: работа с большими текстовыми файлами. »
вопрос как сформировать запрос - чтоб результат потом выводился в др файл.
Space-06, тогда хотелось бы увидеть реальный пример:
файл csv »
поскольку приведённый Вами выше пример — как бы не CSV.
Предположим, что файл — CSV (хорошо бы ещё, для чистоты, иметь текстовые поля заключёнными в кавычки, а так придётся, как минимум, сделать десятичным разделителем точку), например, такого вида:
Source.txt
07.06.2011 8:01, 62.80.230.41, еее.еее.еее.еее, TCP, 3389, 1875, 0.022325, 10
07.06.2011 8:03, 62.80.230.41, еее.еее.еее.еее, TCP, 3389, 1875, 0.05, 10
07.06.2011 8:01, 81.23.3.110, еее.еее.еее.еее, TCP, 3389, 1987, 0.022293, 10
08.06.2011 9:02, 81.23.3.110, еее.еее.еее.еее, TCP, 3389, 1987, 0.06, 10
Тогда, файл Schema.ini может выглядеть примерно так:
[Source.txt]
ColNameHeader=False
Format=Delimited(,)
TextDelimiter=none
CharacterSet=ANSI
Col1=DateTime Date
Col2=IPAddress char
Col3=Name char
Col4=Protocol char
Col5=Port Integer
Col6=SomeField1 Integer
Col7=Cost Float
Col8=SomeField2 Integer
А само приложение — наподобие:
AutoItSetOption("MustDeclareVars", 1)
Local Const $adOpenStatic = 3
Local Const $adLockOptimistic = 3
Local Const $adCmdText = 1
Local $oRecordSet = ObjCreate("ADODB.Recordset")
$oRecordSet.Open("SELECT " & _
"FIRST([DateTime]) AS [FDateTime], " & _
"LAST([DateTime]) AS [LDateTime], " & _
"[IPAddress], " & _
"COUNT(*) AS [Count], " & _
"FIRST([Name]) AS [FName], " & _
"SUM([Cost]) AS [TotalCost] " & _
"FROM [" & "Source.txt" & "] " & _
"GROUP BY [IPAddress] ", _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & "E:\Песочница\0058" & ";Extended Properties=""text;""", _
$adOpenStatic, $adLockOptimistic, $adCmdText)
With $oRecordSet.Fields
ConsoleWrite(.Item("FDateTime").Name & @TAB)
ConsoleWrite(.Item("LDateTime").Name & @TAB)
ConsoleWrite(.Item("IPAddress").Name & @TAB)
ConsoleWrite(.Item("Count").Name & @TAB)
ConsoleWrite(.Item("FName").Name & @TAB)
ConsoleWrite(.Item("TotalCost").Name & @CRLF)
EndWith
ConsoleWrite("------------------------------------------------------------------------------------" & @CRLF)
While Not $oRecordSet.EOF()
With $oRecordSet.Fields
ConsoleWrite(.Item("FDateTime").Value & @TAB)
ConsoleWrite(.Item("LDateTime").Value & @TAB)
ConsoleWrite(.Item("IPAddress").Value & @TAB)
ConsoleWrite(.Item("Count").Value & @TAB)
ConsoleWrite(.Item("FName").Value & @TAB)
ConsoleWrite(.Item("TotalCost").Value & @CRLF)
EndWith
$oRecordSet.MoveNext
WEnd
ConsoleWrite("------------------------------------------------------------------------------------" & @CRLF)
$oRecordSet.Close
$oRecordSet = 0
Exit(0)
где:
E:\Песочница\0058
— путь к текстовому файлу «Source.txt» и лежащему рядом с ним «Schema.ini».
Результат работы скрипта:
FDateTime LDateTime IPAddress Count FName TotalCost
------------------------------------------------------------------------------------
20110607080100 20110607080300 62.80.230.41 2 ХХХ.ХХХ.ХХХ.ХХХ 0.072325
20110607080100 20110608090200 81.23.3.110 2 ХХХ.ХХХ.ХХХ.ХХХ 0.082293
------------------------------------------------------------------------------------
…чтоб результат потом выводился в др файл.
Приведите для этого пример результирующего файла.
Space-06, изучай
; #include <Array.au3> ; для _ArrayDisplay
$text = FileRead(@ScriptDir&'\список.txt')
If StringInStr($text, @LF) Then
$aText=StringSplit(StringStripCR(StringStripWS($text, 7)), @LF) ; делим данные построчно в массив, удалив симовол @CR и повтор пробела
Else
$aText=StringSplit(StringStripWS($text, 7), @CR)
EndIf
Global $aTable[$aText[0]+1][9] ; создаём новый массив с 9-ю колонками
$aTable[0][0]=$aText[0]
; заполняем массив 9-ти колоночный, раздробив строку на колонки по пробелам
For $i = 1 to $aText[0]
$aTmp=StringSplit($aText[$i], ' ')
For $j = 1 to $aTmp[0]
$aTable[$i][$j-1]=$aTmp[$j]
Next
Next
$aOut=_Calculate($aTable) ; функция подсчёта
; _ArrayDisplay($aOut, 'aOut')
$Out=''
For $i = 1 to $aOut[0][0] ; объединение массива в многострочный текст
$aOut[$i][0]&=@TAB&$aOut[$i][1]
$Out&=$aOut[$i][0]&@CRLF
Next
$file = FileOpen(@ScriptDir&'\новый список.txt',2) ; записываем в файл
FileWrite($file, $Out)
FileClose($file)
Func _Calculate($a)
Local $k, $ind, $i
If Not IsArray($a) Or UBound($a)<2 Then SetError(1, 0, 'проблема массива') ; проверка валидности массива
$ind='_//' ; индекс для непересечения с переменными функции
Assign($ind, 2, 1)
$k=0
For $i = 1 To $a[0][0]
If Not IsDeclared($a[$i][2]&$ind) Then
$k+=1
$a[$k][0]=$a[$i][2]
EndIf
Assign($a[$i][2]&$ind, Eval($a[$i][2]&$ind)+StringReplace($a[$i][7], ',', '.'), 1) ; создаём локальные переменные или увеличиваем значение для уже созданных
Next
If $k = 0 Then Return SetError(1, 0, 'проблема массива')
ReDim $a[$k+1][2]
For $i = 1 to $k
$a[$i][1]=Eval($a[$i][0]&$ind)
Next
$a[0][0]=$k
Return $a
EndFunc
Space-06
30-06-2011, 07:41
Iska, а схема какая должна быть для csv?
[Source.csv]
ColNameHeader=False
Format=CSVDelimited
TextDelimiter=none
CharacterSet=ANSI
Col1=DateTime Date
Col2=IPAddress char
Col3=Name char
Col4=Protocol char
Col5=Port Integer
Col6=SomeField1 Integer
Col7=Cost Float
Col8=SomeField2 Integer
а результат должен быть:
IPAddress и TotalCost
Iska, а схема какая должна быть для csv? »
Всё зависит от формата конкретного Вашего файла. Ориентируйтесь в поиске на примерно такой запрос: "Schema.ini" (http://www.google.ru/search?q=%22Schema.ini%22).
а результат должен быть:
IPAddress и TotalCost »
Значит, в:
$oRecordSet.Open("SELECT " & _
"FIRST([DateTime]) AS [FDateTime], " & _
"LAST([DateTime]) AS [LDateTime], " & _
"[IPAddress], " & _
"COUNT(*) AS [Count], " & _
"FIRST([Name]) AS [FName], " & _
"SUM([Cost]) AS [TotalCost] " & _
"FROM [" & "Source.txt" & "] " & _
"GROUP BY [IPAddress] ", _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & "E:\Песочница\0058" & ";Extended Properties=""text;""", _
$adOpenStatic, $adLockOptimistic, $adCmdText)
(ну, и далее — в выводе) можно оставить только эти поля. Я привёл остальное скорее как образец того, каких результатов можно добиться применением технологий баз данных даже относительно обычных текстовых файлов.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC