【问题标题】:How to match lines in one file against lines in another?如何将一个文件中的行与另一个文件中的行匹配?
【发布时间】:2013-08-29 04:16:34
【问题描述】:

我知道这里出了点大问题,但我是 Perl 的新手,希望做以下事情:

在 all.css 中找到所有包含未使用的 CSS 行的行并执行一些逻辑。我的代码的结构方式似乎无法匹配:

if ($lineA =~ /$lineU/) #如果all.css中的行包含unused.css中的行

因为变量是单独定义的。

我将如何构建程序以便能够将 all.css 中的行与未使用的.css 中的行进行匹配?

我的程序如下:

#!/usr/bin/perl

use strict;
use warnings;

open(my $unused_handle,'<', "unused.css") or die $!;
open(my $all_handle,'<',"all.css") or die $!;
open(my $out, '>' ,'lean.css') or die $!;

my $lineU = q{};
my $lineA = q{};

print $out "$lineU";

while($lineU =<$unused_handle>) {

    print $out "$lineU";
    #print $out "$lineA";  Line One not printed from All
    while($lineA =<$all_handle>) {

        if ($lineA =~ m/$lineU/sxm) {

            print "Huza!\n";
        }

        else {
            print "No Match\n";
        }

    }

}

close ($unused_handle);
close ($all_handle);
close ($out);

print "Done!\n";

exit;

下面是我的输入文件示例。

unused.css 中的示例行:

audio, canvas, video
audio:not([controls])
[hidden]
h6

all.css 中的示例行:

article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary {
    display: block;
}
audio, canvas, video {
    display: inline-block;
    *display: inline;
    *zoom: 1;
}
audio:not([controls]) {
    display: none;
    height: 0;
}
[hidden] {
    display: none;
}

【问题讨论】:

  • my $infile=&lt;unused.css&gt;;
  • 我正在尝试定义文件名。你有什么推荐的?
  • 直接打开它:open(my $unused_handle,'&lt;', "unused.css") or die $!; - 之后您可以使用文件句柄,例如while (my $line=&lt;$unused_handle&gt;)
  • my $infile="unused.css"; open(my $unused,'&lt;', $infile) or die $!; 但是,使用两个不同的名称很奇怪。我会选择my $unused_qfn="unused.css"; open(my $unused_fh,'&lt;', $unused_qfn)。使用 var 作为文件名是很好的,因为您可以将其包含在错误消息中:die "Can't open $unused_qfn: $!\n";
  • (有没有其他问题没时间看)

标签: perl string-matching


【解决方案1】:

试试:

if ($lineA =~ m/$lineU/sxm)

另外,请考虑文件中可能有不同行尾的可能性,并在执行比较之前去除行尾。

最后,我希望您通过在开始您的 while 循环之前拉一行来认识到您忽略了每个文件的第一行。

my $lineU = <$unused>;
my $lineA = <$all>;

如果你不想这样做,最好这样初始化:

my $lineU = q{};
my $lineA = q{};

【讨论】:

  • unused.css 中的每一行都完全包含在 all.css 中,因为从 used.css 中提取了它。我会试试这个。
  • 试过这个,仍然没有匹配。我不认为这些变量是一起评估的。据我了解,“sxm”是什么意思?
  • 你到底做了什么改变?对于修饰符: > m 将字符串视为多行。也就是说,将“^”和“$”从匹配字符串的开头或结尾更改为匹配字符串中任何位置的任何行的开头或结尾。 > s 将字符串视为单行。即改“.”。匹配任何字符,甚至是换行符,通常它不会匹配。 > x 通过允许空格和 cmets 扩展模式的易读性。 “/x”中的详细信息
  • 感谢您的帮助。 +1。我的更改已在问题中可见。
【解决方案2】:

我希望这个(未经测试的)sn-p 对你有所帮助:

#!/usr/bin/perl

use strict;
use warnings;

open(my $unused,'<', "unused.css") or die $!;
open(my $all,'<',"all.css") or die $!;

# store all lines of unused.css in a hash
my %unused_line;
while (<$unused>) {
    #remove newlines
    chomp();
    #store the line as a key with empty value
    %unused_line{$_}="";
}
close ($unused);

#...for every line in all.css
while (<$all>) {
    #have we seen it in unused.css (at least everything before ' {')
    if ((m/^(.*\S+)\{/) && (exists $unused_line{$1}))
    {
        #a match - found a line of unused.css in all.css
    }else{
        #no match  - line does not exists in unused.css
    }
}
close ($all);

【讨论】:

  • 哈希似乎有语法错误:%unused_line{$_}="";
  • 我很好奇为什么你更喜欢在这里使用散列而不是数组,特别是因为你不使用键值。
  • 啊应该是$unused_line{$_}=""; 而不是%unused_line{$_}="";
  • 但很遗憾没有匹配项。
  • { 前面的空格重要吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2013-05-29
  • 2012-09-14
  • 2011-04-26
  • 1970-01-01
相关资源
最近更新 更多