Strona 1 z 2

perl - własny skrypt do poszukiwań informacji nie działa

: 14 maja 2009, 00:12
autor: maxblink
Witam, zacząłem z kolegą pisać skrypt w perlu (bardziej on, ja tyle co wyszukałem informację na forach i to od siebie dodałem) i stanęliśmy w martwym punkcie. Myśleliśmy że jest skończony... Chceliśmy go uruchomić i brak reakcji? Może ktoś poradzić coś?
Nasz skrypt:

Kod: Zaznacz cały

#!/usr/bin/perl

my $dir = "." ;

opendir(DIR, $dir) or die("Nie mozna otworzyc katalogu\n");
my @files = readdir(DIR);
closedir(DIR);

open(OUT, ">/home/wyniki/list");

foreach my $file (@files)
{
        next if($file eq "." || $file eq "..");
        $file =~ /([^\/]*?)$/;
        my $account = $1;
        open(DATA, $file) or die("Brak dostepu do pliku $plik");
        my @rawdata = <DATA>;
        foreach my $line (@rawdata)
        {
                if($line =~ /command_groups (\d+)/)
                {
                        print OUT "$account $1";
                }
        }
        close(DATA);
}
close(OUT);

: 14 maja 2009, 10:04
autor: lis6502
Nim ktoś weźmie się za analizę kodu, byłoby miło gdybyś napisał JAK ma działać i dlaczego nie działa, co się dzieje etc.

: 14 maja 2009, 13:07
autor: lessmian2
Jak byś podał wynik polecenia w katalogu w którym się chcesz odpalać ten skrypt i przykładową strukturę plików na których ma operować. Poza tym nie bardo rozumiem co autor miał na myśli w tym momencie
/([^\/]*?)$/;
Tzn nie tyle nie wiem co to znaczy, tylko nie wiem co chciałeś tym osiągnąć ;-)

: 14 maja 2009, 23:40
autor: maxblink
Pliki mniej więcej wyglądają tak:

Kod: Zaznacz cały

BNET\\auth\\command_groups"="7"
"profile\\location"="Loading... 97%"
"BNET\\acct\\passhash1"="c50fea87e5320ca1e8fdf91b4cd0749072c62356"
"friend\\count"="14"
"friend\\17\\uid"="3183"
"friend\\6\\uid"="803"
"friend\\14\\uid"="3183"
"friend\\4\\uid"="404"
"friend\\7\\uid"="2039"
"friend\\12\\uid"="3176"
"BNET\\acct\\ctime"="1238928030"
"friend\\8\\uid"="2762"
"friend\\3\\uid"="1939"
"friend\\13\\uid"="3183"
"friend\\1\\uid"="868"
"friend\\2\\uid"="1810"
"friend\\15\\uid"="3183"
"BNET\\acct\\lastlogin_ip"="78.159.80.4"
"friend\\0\\uid"="2054"
"friend\\10\\uid"="2410"
"friend\\11\\uid"="1828"
"BNET\\acct\\email"=""
"BNET\\acct\\lastlogin_clienttag"="D2XP"
"BNET\\acct\\lastlogin_time"="1242322459"
"friend\\16\\uid"="3183"
"BNET\\acct\\userid"="1942"
"friend\\18\\uid"="3183"
"friend\\19\\uid"="3183"
"BNET\\auth\\lockk"="false"
"BNET\\acct\\username"="dzejson"
"friend\\9\\uid"="2714"
"friend\\5\\uid"="1962"
"profile\\description"=""
"profile\\sex"=""
i chodzi mi o to co jest w pierwszej linijce, owa cyfra określa ilość uprawnień, które są pod cyframi od 1 do 8 (mogą być różne kombinacje np. 1256, 143, 12345678, itp., itd.).

A w wyniku przeszukiwania katalogu, w którym są pliki o zawartości podobnej do wyżej wymienionej chciałbym żeby wypisał wszystkie nazwy plików, w których pojawiło się więcej niż uprawnienie 1. ¯eby to mniej więcej tak wyglądało:

Kod: Zaznacz cały

nazwa_pliku 1256
nazwa_pliku 143
nazwa_pliku 12345678
Gdzie nazwa_pliku to tzw. nazwa konta, które znajduje się w ,,pvpgn/var/users'' (są tam pliczki o nazwach kont, a jako zawartość mają coś podobnego do tej wyżej wymienionej).

Nie wiem czy dobrze to określiłem, jakby coś było nie jasne to dopowiem bo zależy mi na tym skrypcie.

: 15 maja 2009, 15:05
autor: lessmian2
To tak dla pewności ;-) Masz katalog z takimi plikami:
użytkownik1
użytkownik2
użytkownik3
użytkownik4
...
o takiej zawartości:
BNET\\auth\\command_groups"="7"
"profile\\location"="Loading... 97%"
"BNET\\acct\\passhash1"="c50fea87e5320ca1e8fdf91b4cd0749072c62356"
"friend\\count"="14"
"friend\\17\\uid"="3183"
...
Chcesz otrzymać listę
użytkownik1 XXX
użytkownik2 XXX
...
gdzie użytkownikY to nazwa pliku, a XXX to liczba z pierwszej linijki pliku.

No to jeśli tak to skrypt w perlu może wyglądać np tak:

Kod: Zaznacz cały

#!/usr/bin/perl -w
use strict;

my $dir = '.';
my $log_dir = '/sciezka/do/pliku.log';

opendir(DIR, $dir) || die ("Nie mozna otworzyc katalogu $dir :: $!");
open(OUT, '>',$log_dir) || die ("Nie mozna otworzyc pliku $log_dir :: $!");
while(my $file = (readdir DIR)){
        next if($file eq "." || $file eq ".." || $file eq $0);
        open(DATA, $file) or die("Brak dostepu do pliku $file :: $!");
        while (<DATA>){
                print OUT "$file $1\n" if $_ =~ /command_groups"="(\d+)/
        }
        close DATA;
}
close OUT;
closedir DIR ;
Ale czy nie prościej zrobić tego np tak:

Kod: Zaznacz cały

awk -F'"' '/command_groups"="[0-9]+"/ {print FILENAME" "$3}' *
uruchamiając powyższe w katalogu z tymi plikami?

: 16 maja 2009, 00:16
autor: maxblink
Może i lepiej ale wole by mi się zapisywało do pliku, a po drugie te wartości są jako hex czy coś i np.:
jak tam jest wartość 255 - to chciałbym by mi w pliku z wynikiem pokazywało ją jako wartość 12345678, zaś wartość 3 - odpowiednikiem będzie 12... A i tych gdzie było by samo 1 - odpowiednik oczywiście to też 1., żeby nie pokazywało.

Czy umiałby ktoś to na tej zasadzie przerobić?

: 16 maja 2009, 15:45
autor: lessmian2
a po drugie te wartości są jako hex czy coś
No to hex czy 'coś'? Postaraj się może bardziej precyzyjnie wyrażać. Jeśli te wartości są w systemie szesnastkowym, a chcesz wyniki otrzymać w systemie dziesiętnym, to zmodyfikuj linię

Kod: Zaznacz cały

print OUT "$file $1\n" if $_ =~ /command_groups"="(\d+)/ 
na

Kod: Zaznacz cały

print OUT "$file ".hex($1)."\n" if $_ =~ /command_groups"="(\w+)/ 
Reszta kodu bez zmian.

: 16 maja 2009, 22:57
autor: maxblink
lis6502, wiem że lipnie to opisałem - sam się do końca nie rozumiem - ale teraz już wiem o co mi chodzi.

Chodzi o to by w tamtej linijce pokazywało wynik w systemie binarnym (czyli zmieniało z systemu dziesiętnego na binarny, i binarny wpisywało przy nazwie konta jako wynik).

Teraz bardziej zrozumiale?

: 16 maja 2009, 23:00
autor: lis6502
maxblink pisze: teraz bardziej zrozumiale ?
Jasne.
Dopiero raczkuję w perlu, więc strzelam

Kod: Zaznacz cały

print OUT "$file ".bin($1)."\n" if $_ =~ /command_groups"="(\w+)/ 
Ewentualnie jeżeli dane wejściowe są podawane w formie oktalnej

Kod: Zaznacz cały

print OUT "$file ".bin(oct($1))."\n" if $_ =~ /command_groups"="(\w+)/  

: 16 maja 2009, 23:07
autor: maxblink

Kod: Zaznacz cały

Undefined subroutine &main::bin called at ./show line 13, <DATA> line 4.
Niestety ale to chyba jakoś inaczej trzeba zapisać?