txt Dosyasi icerisindeki sayilarin adedini almak

Başlatan lsari86, 29 Ağustos 2013 - 21:04:58

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

lsari86

Arkadaşlar ofisde kullandığımız yazılımlardan bir tanesi aşağıdaki gibi bir log çıktısı veriyor.
Log dosyasında 1 ile 34 arasında her bir hata/ işlem için bir sayı numarası basılmakta.
örnk: 4 --> yetkisiz erişim vb.
Bende bir script ya da uygulama ile bu log dosyasında ki hata kodlarını sayısını almak istiyorum.

Yazacağım uygulama log dosyasını okuyup içerisinde kaç numaralı hata kodundan kaç adet basıldığını bana ayrı bir çıktı olarak vermeli.

Örnk: 34 -> 20 adet
           12 -> 12 adet gibi.

Bir kaç şey konuştuk arkadaşlar ile ama pek çıkamadık işin içinden.
Keza benim aklıma gelen ve ilk etapda yapmasını istediğim şey yazılabilecek bir metod log dosyasının yolunu vermek ve bu log.txt yi okutup sonucu çıktı olarak başka bri txt dosyasına verdirmek.
Konu hakkında önerileriniz nedir?
Benimle de paylaşa bilirseniz çok memnun olurum.
Kolaylıklar...


Log.txt dosyasının içeriği
23 44 19 27 46 39 32 05 51 26 53 12 21 03 17 07 46 30 32 48 51 06 35 16 35 12 52 48 07 14 46 29 40 32 31 26 34 21 51 14 47 22 23 38 21 09 41 31 34 30 33 11 29 51 51 10 43 46 14 20 52 51 44 02 42 05

guopx

#1
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import csv

path = sys.argv[1]
print path
log = open("%s" %(path), 'r')
for line in log.readlines():
    liste = []
    for element in line[0:-1].split(' '):
        liste.append(element)

for hata in range(1, 34):
    sayi = liste.count("%s" %(hata))
    if sayi is not 0:
       print "%s => %s adet" %(hata, sayi)


Python'un liste özellikleri ile basit bir betik yazdım işinini görür bence.  Betiği kaydedip çalıştırılabilir yaptıktan sonra ./betik /nerede/bu/log şeklinde çalıştırıp sonuçları alabilirsiniz.
mesela log.txt bu:
Log.txt dosyasının içeriği
23 44 19 27 46 39 32 05 51 26 53 12 21 03 17 07 46 30 32 48 51 06 35 16 35 12 52 48 07 14 46 29 40 32 31 26 34 21 51 14 47 22 23 38 21 09 41 31 34 30 33 11 29 51 51 10 43 46 14 20 52 51 44 02 42 05
ve masaüstüne kaydettim. Betiği de masaüstüne logparser adıyla kaydettim. Şimdi masaüstüne uçbirim açıp ./logparser ~/Masaüstü/log.txt yazınca çıktı 10 => 1
11 => 1
12 => 2
14 => 3
16 => 1
17 => 1
19 => 1
20 => 1
21 => 3
22 => 1
23 => 2
26 => 2
27 => 1
29 => 2
30 => 2
31 => 2
32 => 3
33 => 1
Şeklinde oldu. Olmayan yani 0 adet olan hataları basmıyor ve sadece 1 ile 34 arasındaki hataları basıyor (başta Log dosyasında 1 ile 34 arasında her bir hata/ işlem için bir sayı numarası basılmakta demiştiniz o yüzden 1 34 arası) Umarım işinizi görür :)


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 29 Ağustos 2013 - 22:44:40

Eğer hata numaraları 1-34 ten fazla ise for hata in range(1, 34): satırından genişletip daraltabilirsiniz aralığı.
Sevdiklerine sevdiğini söyle çok geç olmadan.

ekremsenturk

log dosyasını data - read ile okutup, while dögüleri ve if koşulları kullanarak ve eşit/eşit_değil mantıksal operatörleri ile kıyaslama yaptıktan sonra, sonuçları yeni dosya açıp, yazdırmak mümkün olmalı. Detaylar ve kullanacağınız betik size kalmış.

travego0403

@ekremsenturk Dediğiniz doğru ama uygun bir yaklaşım değil. Kodun içerisini 'if'lerle doldurmak pek uygun bir yaklaşım değil. Orada 34 hata çeşidi varsa siz 34 tane if şartı mı yazacaksınız?. Bunun yerine @guopux'un kullandığı gibi bir mantık kullanmak daha uygun. C/C++  dilinde yazarsak, 34 çeşit hata kaydı olduğunu düşünürsek,
bir dizi ele alalım int dizi[34] ve bütün elemanlarını sıfıra eşitleyelim,
ilk hata kodunu okuyalım, x olsun
x in sayısının tutulduğu dizi elemanını bir arttıralım, dizi[x]++
ikinci hata kodunu okuyalım, y olsun
y nin sayısının tutulduğu dizi elemanını bir arttıralım, dizi[y]++
üçüncü hata kodunu okuyalım, x olsun
x in sayısının tutulduğu dizi elemanını bir arttıralım, dizi[x]++

Bu işlem dosyanın sonuna kadar tekrar edilirse istenilen gerçekleştirilmiş olur.


"Matematik bir dildir ve bu dilde şairlere fizikçi denir." Richard Feynman

guopx

#4
Biraz inceleyince betiğin eksik çalıştığını anladım 01, 05, 09 gibi tek haneli hataları yakalamıyor çünkü range() den çıkan sayılar 1, 5, 9 şeklinde. Range yerine set(liste) ile liste içindeki her elemanı for döngüsüne katıp doğru sonucu elde edebilirsiniz#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import csv

path = sys.argv[1]
print path
log = open("%s" %(path), 'r')
for line in log.readlines():
    liste = []
    for element in line[0:-1].split(' '):
        liste.append(element)

for hata in list(set(liste)):
    sayi = liste.count("%s" %(hata))
    if sayi is not 0:
       print "%s => %s adet" %(hata, sayi)

Son şekli bu.


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 29 Ağustos 2013 - 23:58:58

Hatta sonucu sıralamak için sorted ile listeyi sıralayıp düzgün bir çıktı elde edebiliriz:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import csv

path = sys.argv[1]
print path
log = open("%s" %(path), 'r')
for line in log.readlines():
    liste = []
    for element in line[0:-1].split(' '):
        liste.append(element)

for hata in sorted(list(set(liste))):
    sayi = liste.count("%s" %(hata))
    if sayi is not 0:
       print "%s => %s adet" %(hata, sayi)

Tamam başka düzenleme yok en en son hali bu :)
Sevdiklerine sevdiğini söyle çok geç olmadan.

ironic

#5
Bash çözümü


#!/bin/bash

#log dosyası adı ve konumuyla birlikte girilmeli.
log_dosyasi=log
for i in $(seq -w 1 34);  do  echo "$i -> $(tr -s ' ' '\n' <$log_dosyasi | grep -cw $i)";  done


Güncelleme

#!/bin/bash

# en büyük hata kodu numarası
eb_hata_kodu=34
# en küçük hata kodu numarası
ek_hata_kodu=1
# log dosyasi değişmez ada sahipse sürekli betiğe değişken olarak
# vermek yerine dosyanın konumuyla birlikte adını buraya yazın.
log_dosyasi=log

(( $#==2 )) && { # log dosyası ve çıktı dosyası betiğe verilmişse
  [[ -r $1 ]] && girdi_dosyasi="$1" || exit 1
  cikti_dosyasi="$2"
} || { # verilmemişse
  # log_dosyasi girilmiş ve ulaşılabilir ise onu kullan.
  [[ -r $log_dosyasi ]] && girdi_dosyasi="$log_dosyasi" || exit 1
  # cikti dosyası girilmediği için sonuçlar uçbirim ekranına basılacak.
  cikti_dosyasi=/dev/stdout
}

# dosya içerisindeki boşlukları yeni satırlarla değiştirdik.
log_icerigi="$(tr -s ' ' '\n' <"$girdi_dosyasi")"

for i in $(seq -w $ek_hata_kodu $eb_hata_kodu)
do
  echo "$i -> $(grep -cw $i <<<"$log_icerigi")"
done > "$cikti_dosyasi"

sonuç:


01 -> 0
02 -> 1
03 -> 1
04 -> 0
05 -> 2
06 -> 1
07 -> 2
08 -> 0
09 -> 1
10 -> 1
11 -> 1
12 -> 2
13 -> 0
14 -> 3
15 -> 0
16 -> 1
17 -> 1
18 -> 0
19 -> 1
20 -> 1
21 -> 3
22 -> 1
23 -> 2
24 -> 0
25 -> 0
26 -> 2
27 -> 1
28 -> 0
29 -> 2
30 -> 2
31 -> 2
32 -> 3
33 -> 1
34 -> 2

burk


lsari86

Arkadaşlar hepinizin bir birinden değerli yanıtlarını okuyup elimden geldiğince bir şeyler yapmak istedim.
Son durumu şöyle açıklamak istiyorum...
Keza İnsanoğlu sanırım her şeyin çok daha iyisini,rahatını ve kolayını istiyor devamlı.
Bu iyi bir şey mi bilemiyorum ama kaç gündür uğraştığım şeyin sonucunda tamda sizinde destekleriniz ile istediğim türde bir ürün aldım derken bu seferde bu işin daha pratik bir yolu yok mu diye düşünmeye başladım.
Keza şuana kadar yaptığım adımları gözden geçirince epey uğraştığımı gördüm.
Öyle ki intranet de kullandığımız uygulama ile ilgil günlük logları takip ve okuma işi için şöyle bir yol izliyoruz.
1-)Client lar makine üzerindeki uygulamaya erişip her işlem yaptıkça makine her yapılan işlem sonucunda 192.168.x.y de bir log çıktısı veriyor.
Bende aşağıda yazdığım php kodu ile(localhost/levent/parseTarih.php) erişim tarihlerini okuyup, get_numbers('20130829'); formatın da ekrana basıyorum.

<?php
 
function cekecek($site)
    {
        if(
function_exists('curl_exec')) {
            
$ch curl_init();
            
curl_setopt($ch,CURLOPT_URL$site);
            
curl_setopt($ch,CURLOPT_USERAGENT'Mozilla/5.0 (X11; U; Linux i686; tr-TR; rv:1.9.0.3) Gecko/2008092818 Pardus/2008 Firefox/4.0.0');
            
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
            
curl_setopt($chCURLOPT_HEADER1);
            
curl_setopt($oturumCURLOPT_SSL_VERIFYPEERfalse);
                       
            
$return curl_exec($ch);
            
curl_exec($ch);
            return 
$return;
        }
        else{
            return 
file_get_contents($site);
        }
    }
$source cekecek('http://192.168.x.y/sonuclar/logTarihleri.php?tur=islem');   
preg_match_all('#"tarih"\:"(.*?)"#si',$source$parse);
   
foreach(
$parse[1] as $element)
        echo 
'get_numbers(\'' .$element .'\');' ' ''<br/>';
?>

ÇIKTISI:
get_numbers('20130819'); 
get_numbers('20130810'); 
get_numbers('20130809'); 
get_numbers('20130808');


2-)localhost/levent/parseTarih.php ile ekrandan aldığım tarihleri kopyalayıp aşağıdaki php koduna elle yapıştırıyorum.
daha sonra aşağıda yazdığım php kodunu localhost/levent/parse.php olarak çağırıyorum ve neticede tek tek hata kodlarını alıyorum.
-----------------------------------------------------------------------------------------------------------------------------
<?php
       
function cekecek($site)
            {
                    if(
function_exists('curl_exec')) {
                            
$ch curl_init();
                            
curl_setopt($ch,CURLOPT_URL$site);
                            
curl_setopt($ch,CURLOPT_USERAGENT'Mozilla/5.0 (X11; U; Linux i686; tr-TR; rv:1.9.0.3) Gecko/2008092818 Pardus/2008 Firefox/4.0.0');
                            
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
                            
curl_setopt($chCURLOPT_HEADER1);
                            
//curl_setopt($ch,CURLOPT_COOKIEJAR,"cookies.txt");
                            //curl_setopt($ch,CURLOPT_COOKIEFILE,"cookies.txt");
                            
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
                                                  
                            
$return curl_exec($ch);
                            
curl_exec($ch);
    
                            return 
$return;
                    }
                    else{
                            return 
file_get_contents($site);
                    }
            }
     function 
get_numbers($date) {
    
$source cekecek('http://192.168.z.t/sonuclar/logTarihleri/islem/'.$date.'.php');
    
preg_match_all('#"rakamlar"\:"(.*?)"#si'$source$parse);
    foreach(
$parse[1] as $element)
       
        
//echo str_replace("#", " ",$element) . ' ';
        
echo str_replace("#"" ",$element) . ' '.'<br/>';
        }
get_numbers('20130819'); 
get_numbers('20130810'); 
get_numbers('20130809'); 
get_numbers('20130808');
?>

ÇIKTISI :
23 44 19 27 46 39 32 05 51 26 53 12 21 03 17 07 46 30 32 48 51 06 35 16 35 12 52 48 07 14 46 29 40 32 31 26 34 21 51 14 47 22 23 38 21 09 41 31 34 30 33 11 29 51 51 10 43 46 14 20 52 51 44 02 42 05


3-)Son olarak da 2. adımda aldığım hata kodlarını isle.php dosyasının içerisine yapıştırıp browserdan localhost/levent/isle.php dosyasını çağırıyorum

<?php
$log
="23 44 19 27 46 39 32 05 51 26 53 12 21 03 17 07 46 30 32 48 51 06 35 16 35 12 52 48 07 14 46 29 40 32 31 26 34 21 51 14 47 22 23 38 21 09 41 31 34 30 33 11 29 51 51 10 43 46 14 20 52 51 44 02 42 05";
$arr=explode(" ",$log);
for(
$i=0$i<count($arr); $i++)
$array[$arr[$i]]++;
arsort($array);
echo 
'<pre>';
print_r($array);
?>

ÇIKTISI :
Array
(
    [51] => 6
    [46] => 4
    [14] => 3
    [21] => 3
    [32] => 3
    [48] => 2
    [30] => 2
    [34] => 2
    [23] => 2
    [31] => 2
    [07] => 2
    [52] => 2
    [29] => 2
    [35] => 2
    [05] => 2
    [26] => 2
    [44] => 2
    [12] => 2
    [11] => 1
    [33] => 1
    [41] => 1
    [10] => 1
    [09] => 1
    [43] => 1
    [42] => 1
    [02] => 1
    [20] => 1
    [38] => 1
    [47] => 1
    [39] => 1
    [03] => 1
    [16] => 1
    [06] => 1
    [27] => 1
    [40] => 1
    [53] => 1
    [17] => 1
    [19] => 1
    [22] => 1
)


Şeklinde oluyor ve istediğimi elde ediyorum.
Ancak burada karşıma çıkan soru 3 seferde yaptığım işi tek seferde nasıl yapa bilirim?
Keza her seferinde yeni tarihleri ve hata kodlarını kopyala yapıştır yapmak yerine web browserdan sadece localhost/levent/isle.php dosyasını çağırsam o benim yerine tüm bu işleri halledip bana sadece çalışmaya başladığı ilk günden beri o güne kadar oluşan logtari hlerini ve hata kodlarını okuyup hangi hata kodundan kaç adet basıldığını verse?
Tüm bu işlemlerini client bir makinede çalışan betikler ile yapmak istemiyorum.
Keza her seferinde bu betikleri kullanacak olan kişinin makinesine kopyalamak gerekecek.
Ancak en azından bir php script olursa herkes kendi makinesinden sadece bir adrese bağlanacak ve böylece karşına sadece sonuçlar gelecek.
Yıl sonu analiz işlemlerinde sırtıma bina yük kurtulmuş olacak.