【问题标题】:How to get a comment printed for each line of text that matches within a file?如何为文件中匹配的每一行文本打印注释?
【发布时间】:2017-02-02 18:10:12
【问题描述】:

我正在尝试从匹配*main_log 的所有文件中匹配一个名为expressions.txt 的文件中给出的关键字/文本/行。当找到匹配项时,我想为匹配的每一行打印注释。

有没有更好的打印方法?

expression.txt
Hello World ! # I want to print this comments#
Bye* #I want this to print when Bye Is match with main_log#
:::
:::

下面是我使用的代码:

{
    open( my $kw, '<', 'expressions.txt' ) or die $!;
    my @keywords = <$kw>;
    chomp( @keywords ); # remove newlines at the end of keywords

    # get list of files in current directory
    my @files = grep { -f } ( <*main_log>, <*Project>, <*properties> );

    # loop over each file to search keywords in
    foreach my $file ( @files ) {

        open( my $fh, '<', $file ) or die $!;
        my @content = <$fh>;
        close( $fh );

        my $l = 0;

        foreach my $kw ( @keywords ) {

            my $search = quotemeta( $kw ); # otherwise keyword is used as regex, not literally

            #$kw =~ m/\[(.*)\]/;
            $kw =~ m/\((.*)\)/;
            my $temp = $1;
            print "$temp\n";

            foreach ( @content ) { # go through every line for this keyword
                $l++;
                printf 'Found keyword %s in file %s, line %d:%s'.$/, $kw, $file, $l, $_ if /$search/;
            }
        }
    }

我尝试使用此代码打印括号 (...) 中提到的 cmets,但它没有以我想要的方式打印,如下所示:

如果表达式.txt 包含

Hello World ! # I want to print this comments#

如果Hello World ! 字符串在我的名为main_log 的文件中匹配,那么它应该只匹配main_log 中的Hello World!,但打印# I want to print this comments# 作为注释以供用户理解关键字。

这些关键字可以是任意长度或包含任意字符。

虽然我在命令提示符上使用了 perl -w Test.pl > my_output.txt 命令,但对将所需的输出打印到文件中有点怀疑,但不确定如何在 perl 脚本本身内部使用

p>
open( my $kw, '<', 'expressions.txt') or die $!;
my @keywords = <$kw>;
chomp(@keywords); # remove newlines at the end of keywords


# post-processing your keywords file
my $kwhashref = {
  map {
    /^(.*?)(#.*?#)*$/;
    defined($2) ? ($1 => $2) : ( $1 => undef )
  } @keywords
}; 


# get list of files in current directory
my @files = grep { -f } (<*main_log>,<*Project>,<*properties>);


# loop over each file to search keywords in
foreach my $file (@files) {
  open(my $fh, '<', $file) or die $!;
  my @content = <$fh>;
  close($fh);
  my $l = 0;
  #foreach my $kw (@keywords) {

  foreach my $kw (keys %$kwhashref) {
    my $search = quotemeta($kw); # otherwise keyword is used as regex, not literally
    #$kw =~ m/\[(.*)\]/;
    #$kw =~ m/\#(.*)\#/;
    #my $temp = $1;
    #print "$temp\n";

    foreach (@content) { # go through every line for this keyword
      $l++;
      if (/$search/)
      {

      # only print if comment defined
      print $kwhashref->{$kw}."\n" if defined($kwhashref->{$kw}) ;    
      printf 'Found keyword %s in file %s, line %d:%s'.$/, $kw, $file, $l, $_
      #printf '$output';

      }


    }
  }
}

【问题讨论】:

  • 还有什么问题?您是否遇到错误,或者您的代码是否执行了您不想要的操作并且您不知道为什么?请具体。您可以edit您的问题并添加详细信息。

标签: perl


【解决方案1】:

您的示例代码的大括号 { ... } 不匹配,无法编译。

如果您要在代码末尾添加另一个右大括号,那么它会编译,但是行

 $kw =~ m/\((.*)\)/;

永远不会成功,因为expressions.txt 中的任何地方都没有括号。如果匹配未成功,则 $1 的值将从最近成功的正则表达式匹配操作中保留

您还尝试根据从expressions.txt 检索到的所有行搜索文件中的行,此时您应该将这些行拆分为关键字及其对应的 cmets

【讨论】:

  • 其实是错别字漏掉了{
  • 关于 () 在表达式中我现在添加了它们.. 谢谢
【解决方案2】:

这似乎是您的另一个问题的answer 的后续行动。我在最后一段中试图建议的内容将在代码的前三行之后开始:

# post-processing your keywords file
my $kwhashref = {
  map {
    /^(.*?)(#.*?#)*$/;
    defined($2) ? ($1 => $2) : ( $1 => undef )
  } @keywords
}; 

现在,您在 hashref 中拥有了关键字,其中包含要搜索的实际关键字作为键,以及 cmets 作为值(如果存在)(在此处使用您的 #comment# 行尾语法)。

您的关键字循环现在必须使用 keys %$kwhashref 并且您现在可以另外打印内部循环中的注释,转换如我链接的答案所示。附加打印:

print $kwhashref->{$kw}."\n" if defined($kwhashref->{$kw}); # only print if comment defined

【讨论】:

  • 它现在工作得很好..刚刚添加了上面的完整代码如果我想将输出打印到文件中..这里有多个 Printf
  • 只是一个小疑问..我怎样才能让我的关键字按顺序而不是随机顺序搜索..就像我的文本文件 Hello World Bye 中有关键字..在所有我想以 Hello 开头的文件,然后是 World,然后是 Bye ..
猜你喜欢
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 2012-02-05
相关资源
最近更新 更多