2016-10-01 6 views
1

Okay ... so versuche ich, ein Wörterbuch mit Crunch und Grep Ich habe versucht, auch Perl statt mit zu machen.Was ist falsch in diesem Grep-Befehl?

crunch 8 12 1234567890 -d [email protected] | grep -v '\([0-9]\) .*\1.*\1.*\1.*' | grep 41106041 

Also, im Grunde möchte ich alle Passwörter filtern, die Zahlen erscheinen 3 mal

grep 41106041 

ist nur zu testen, ob der Code funktioniert .. und es funktioniert nicht.

Ich habe auch versucht, einige „C-Stil“ Perl-Code, wie ich noch ein Neuling bin Perl:

#! /bin/perl 
@lines=<STDIN>; 
$c=0; 
foreach $number(@lines) 
{ 
    $acum=undef; 
    $pos=0; 
    while($pos <= &countdig($number)) 
    { 
     if ($acum=$digit) 
     { 
      $c=$c+1; 
     } 
     else 
     { 
      $c=0; 
     } 
     $acum=$digit; 

    } 
    if ($c=3) 
    { 
     print "$number"." "; 
    } 
    $c=0; 
} 

sub countdig 
{ 
    my($j)=0; 
    chomp(my(@n)[email protected]_); 
    print "first dig $n[$j] \n"; 
    while($_[0][$j]>=0 && $_[0][j]<=9) 
    { 
     $j+=1; 

    } 
    print "j total : $j \n"; 

    $j; 
} 

Countdig soll die Anzahl der Ziffern zählen, aber was ist .. Ich kann‘ t Zugriff auf eine skalare Variable als Liste .. so gut, wenn Sie mir erklären könnten, wie es funktioniert, wäre es sehr geschätzt.

Antwort

3

Ihre grep versagt, weil es eine Streu Platz in Ihrem Muster, und Sie für 4 identische Ziffern suchen (das erfasste ein, plus drei weiteren von Rückreferenzierung).

$ printf '12345678\n41106041\n87654321\n' | grep -v '\(.\).*\1.*\1' 
12345678 
87654321 

Das Problem ein Neuling auf Perl ist nicht zu sein, denn es ist eine C-Lösung zu drehen

// For each line 

char *num = ...; 

int digits[10]; 
for (int i=0; i<10; ++i) { 
    digits[i] = 0; 
} 

const char *p = num; 
int triple = 0; 
for (; *p && *p != '\n'; ++p) { 
    if (++digits[*p - '0'] == 3) { 
     triple = 1; 
     break; 
    } 
} 

if (triple) { 
    ... 
} 

in eine Perl-Lösung

while (my $num = <>) { 
    chomp($num); 

    my @digits; 
    my $triple; 
    for my $digit (split //, $num) { 
     if (++$digits[$digit] == 3) { 
     $triple = 1; 
     last; 
     } 
    } 

    say $num if $triple; 
} 

Natürlich einfach ist, ein Perl-Programmierer verwenden möglicherweise den gleichen Ansatz, den Sie für grep verwendet haben.

while (<>) { 
    if (!/(.).*\1.*\1/) { 
     print; 
    } 
} 
+0

Es gibt auch ein Leerzeichen nach der ersten Ziffer im OP-Versuch. – tripleee

+0

Eine Lösung in c war nicht das Problem, aber danke trotzdem. Ich habe das Skript in Perl gegen Grep getestet und es scheint, Perl handle Bruteforce-Daten viel effektiver. Nochmals vielen Dank für die Beantwortung einer so dummen Frage, es hat mir sehr geholfen. –

+0

Es ist effizient, weil es * nicht * rohe Gewalt ist. Es macht höchstens 'length ($ num)' checks. Die Regexp ist eigentlich der Brute-Force-Ansatz und führt zahlreiche Überprüfungen durch – ikegami

0
echo 41106041 | grep -v '\([0-9]\).*\1.*\1.*