2010-11-24 5 views
1

J'ai un fichier d'éléments CSS, et j'essaie de vérifier les éléments CSS en double, puis je produis les lignes qui montrent les lignes de dupe.Découverte des lignes en double

 
    ###Test 
    ###ABC 
    ###test 
    ##.hello 
    ##.ABC 
    ##.test 
    bob.com###Test 
    ~qwerty.com###Test 
    ~more.com##.ABC 

###Test & ##.ABC existe déjà dans la liste, et je voudrais un moyen de sortir les lignes qui sont utilisées dans le fichier, essentiellement vérifier la duplication (sensible à la casse). Donc, en utilisant la liste ci-dessus, je voudrais générer quelque chose comme ça ..

 
    Line 1: ###Test 
    Line 7: bob.com###Test 
    Line 8: ~qwerty.com###Test 

    Line 5: ##.ABC 
    Line 9: ~more.com##.ABC 

Quelque chose dans bash, ou peut-être perl?

Merci :)

Répondre

1

J'ai été mis au défi par votre problème, donc je vous ai écrit un script. J'espère que tu l'as aimé. :)

#!/usr/bin/perl 

use strict; 
use warnings; 

sub loadf($); 

{ 
    my @file = loadf("style.css"); 
    my @inner = @file; 
    my $l0 = 0; my $l1 = 0; my $l2 = 0; my $dc = 0; my $tc; 
    foreach my $line (@file) { 
     $l1++; 
     $line =~ s/^\s+//; 
     $line =~ s/\s+$//; 
     foreach my $iline (@inner) { 
      $l2++; 
      $iline =~ s/^\s+//; 
      $iline =~ s/\s+$//; 
      next if ($iline eq $line); 
      if ($iline =~ /\b$line\b/) { 
       $dc++; 
       if ($dc > 0) { 
        if ($l0 == 0) { 
         print "Line " . $l1 . ": " . $line . "\n"; 
         $l0++; 
        } 
        print "Line " . $l2 . ": " . $iline . "\n"; 
       } 
      } 
     } 
     print "\n" unless($dc == 0); 
     $dc = 0; $l0 = 0; $l2 = 0; 
    } 
} 

sub loadf($) { 
    my @file = (); 
    open(FILE, $_[0] . "\n") or die("Couldn't Open " . $_[0] . "\n"); 
    @file = <FILE>; 
    close(FILE); 
    return @file; 
} 

__END__ 

Ceci fait exactement ce dont vous avez besoin. Et désolé si c'est un peu brouillon.

+0

Trop de problèmes avec ce script, doit vérifier la fin des lignes, de sorte que la ligne 1 781 : ##. test Ligne 1782: ##. test-leaderboard Ligne 1787: ##. abc Ligne 1788: ##. abcng puisque ##. adc n'est pas la même chose que ##. abcng – user349418

+0

@ user349418 modifié, réessayez. – Ruel

1

Cela semble fonctionner:

sort -t '#' -k 2 inputfile 

groupes Il leur par la partie après les caractères #:

##.ABC 
~more.com##.ABC 
###ABC 
##.hello 
##.test 
###test 
bob.com###Test 
~qwerty.com###Test 
###Test 

Si vous voulez voir seulement les valeurs uniques:

sort -t '#' -k 2 -u inputfile 

Résultat:

##.ABC 
###ABC 
##.hello 
##.test 
###test 
###Test 

Cette jolie doublons de près la sortie par exemple dans la question (il repose sur certains éventuellement des fonctionnalités spécifiques GNU):

cat -n inputfile | 
    sed 's/^ *\([0-9]\)/Line \1:/' | 
    sort -t '#' -k 2 | 
    awk -F '#+' '{if (! seen[$2]) { \ 
     if (count > 1) printf "%s\n", lines; \ 
     count = 0; \ 
     lines = "" \ 
    }; \ 
    seen[$2] = 1; \ 
    lines = lines "\n" $0; ++count} 
    END {if (count > 1) print lines}' 

Résultat:

Line 5: ##.ABC 
Line 9: ~more.com##.ABC 

Line 1: ###Test 
Line 7: bob.com###Test 
Line 8: ~qwerty.com###Test 
+0

Je pense que vous pourriez avoir une faute de frappe dans le premier exemple de 'sort'. Est-il possible que vous vouliez taper 'sort -t '#' -k 2 inputfile' (sans le -u)? – martineno

+0

@martineno: Oui, merci. –

0

Voici une façon de le faire, ce qui est assez facile à étendre à plusieurs fichiers si nécessaire.

Avec ce fichier find_dups.pl:

use warnings; 
use strict; 

my @lines; 
while (<>) {          # read input lines 
    s/^\s+//; s/\s+$//;       # trim whitespace 
    push @lines, {data => $_, line => $.} if $_ # store useful data 
} 

@lines = sort {length $$a{data} <=> length $$b{data}} @lines; # shortest first 

while (@lines) { 
    my ($line, @found) = shift @lines; 
    my $re = qr/\Q$$line{data}\E$/;    # search token 
    @lines = grep {        # extract matches from @lines 
     not $$_{data} =~ $re && push @found, $_ 
    } @lines; 
    if (@found) {        # write the report 
     print "line $$_{line}: $$_{data}\n" for $line, @found; 
     print "\n"; 
    } 
} 

puis perl find_dups.pl input.css impressions:

 
line 5: ##.ABC 
line 9: ~more.com##.ABC 

line 1: ###Test 
line 7: bob.com###Test 
line 8: ~qwerty.com###Test 
+0

Essayé cela, mais il ne vérifie pas la fin des lignes, par exemple, ligne 10476: test.com ### plf-ysm ligne 10477: test.com ### plf-ysm-side Arent la même chose. Sinon c'est un script décent :) – user349418

+0

@ user349418 => 'test.com ### plf-ysm' est contenu dans' test.com ### plf-ysm-side' et correspond en fonction des données de test que vous avez données. J'ai fait une modification qui corrige probablement le problème que vous avez, mais la prochaine fois, s'il vous plaît fournir plus de données de test. De plus, si vous pensez qu'une réponse à votre question est correcte, vous pouvez cliquer sur une flèche vers le haut. –

Questions connexes