发现重复的行

时间:2010-11-24 12:47:32

标签: perl bash

我有一个CSS元素文件,我正在尝试检查任何重复的CSS元素,然后输出显示欺骗行的行。

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

###Test& ##.ABC已经存在于列表中,我想要一种方法来输出文件中使用的行,基本上是重复检查(区分大小写)。所以使用上面的列表,我会生成这样的东西..

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

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

bash中的东西,还是perl?

谢谢:)

4 个答案:

答案 0 :(得分:1)

我一直受到你的问题的挑战,所以我写了一个脚本。希望你喜欢它。 :)

#!/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__

这正是您所需要的。对不起,如果它有点乱。

答案 1 :(得分:1)

这似乎有效:

sort -t '#' -k 2 inputfile

它按#字符后面的部分分组:

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

如果您只想查看唯一值:

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

结果:

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

这非常接近重复问题中的示例输出(它依赖于一些可能的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}'

结果:

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

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

答案 2 :(得分:0)

如果您可以安装MoreUtils,我建议使用uniq函数:

how-do-i-print-unique-elements-in-perl-array

答案 3 :(得分:0)

这是一种方法,如果需要,可以很容易地扩展到多个文件。

使用此文件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";
    }
}

然后perl find_dups.pl input.css打印:

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

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