正規表現の一致の一部と他のすべての一致のリストを印刷する方法

正規表現の一致の一部と他のすべての一致のリストを印刷する方法

いくつかのテスト結果を要約しているので、次の種類のテキストがあります。

FAILED src/path/to/code.test.js
  Test Suite
    

答え1

これはもっと仕事ですperl

perl -lne '
  if (/^\h*at\h.*?\((src.*?\.test\.js):(\d+:\d+)\)/) {
    $total{$1}++;
    $lines{$1}->{$2}++
  }
  END {
    for $file (sort {$total{$b} <=> $total{$a}} keys %total) {
      my $l = $lines{$file};
      print "$total{$file} $file (" . 
      join(", ", map "$l->{$_} - $_", sort {$l->{$b} <=> $l->{$a}} keys %$l) . ")"
    }
  }'

Perl正規表現演算子の*?貪欲なバージョンです。私はそれをサポートする実装を*1つだけ知っています(非標準に対応する実装に加えて)。しかし、それがあなたが使っている実装のようです。これはast-openであり、私が知っている限り、どのシステムでもデフォルトで提供されていません。また、ksh93以外のast-openツールを含めるか含めるかを考慮することが知られているIllumosも同様です。 GNU実装(オプションを導入したもの)では、is(0または1先行原子)は(0以上の文字)に適用されるため、and(0または1以上の文字)と同じです。sed-r-Esedsed-r.*??.*.*.+?.*

答え2

awk '/^[[:blank:]]*at.*\(src.*\.test\.js:[0-9]+:[0-9]+\)/{
    split($0, tmp, /[)(:]/) ## Assuming there is no ), ( and : in the filePath
    fileCnt [tmp[2]]++
    fileErrs[tmp[2], tmp[3]":"tmp[4]]++
}

END{
    for (fileName in fileCnt){
        sep=""
        printf ("%s %s (", fileCnt[fileName], fileName)
        for(file in fileErrs){
            split(file, tmp, SUBSEP)
            if(fileName==tmp[1]){
                printf("%s - %s", sep fileErrs[file], tmp[2])
                sep=", "
            }
        }
        print ")"
    }
}' infile   ## or infiles*

関連配列はfileCntファイル名の数だけを保持します。配列のキーはファイル名で、値はそのファイルが見た回数です。関連付けられた
配列は、fileErrs各ファイル名のエラー数を保持します。ここで、キーはfileName + errNumsの組み合わせです。

ENDブロックで処理中です。ファイル数ファイル数を並べて印刷し、fileCnt[fileName]ファイル名自体をfileName処理します。ファイルエラー重要な部分を配置して分割し、最初の部分をファイル名と比較して各ファイルの個々のエラーを見つけます。

答え3

使用幸せ(以前のPerl_6)

~$ raku -ne 'state %h; state $i; ++$i;  \
             if m/ ^ \h* at \h .*?  "(" ~ ")" [(src .*? \.test \.js) \: (\d+ \: \d+)] /   \
             -> { %h.push: $0 => $i ~"|"~ $1 }; END .say for %h;'  file

-neつまり、コードは(非自動印刷)コマンドラインフラグを使用して入力ファイル内で1行ずつ実行されます。ハッシュ値が提供されます%h$iイテレータが宣言されました。各行ごとに$iイテレータがインクリメントされます。if正規表現に一致する条件付きテスト似ているが同じではない@Stephane_Chazelasが投稿したPerl5コードにアクセスしてください。ただし、このRaku正規表現は、素晴らしい(最新の)機能であるRakuのネストされ~たデータ構造チルダ構文を使用します"(" ~ ")" [ … ]。 Raku正規表現は、パス$0とコロンで区切られた数字をキャプチャします$1

一致するものが1行ずつ見つかると、ハッシュに追加されpushます。(パス)はキーとして使用され、値はコードを使用して(使用:使用)キャプチャされた数値部分に関連付けられた行番号になります。ハッシュには重複キーが存在できないため、各キー(パスなど)は異なる値を累積します。読み出しラインの最後にハッシュ値が出力されます。%h$0~$1$i ~"\t"~ $1END%h

入力例:

#See above. OP's original file was concatenated 5 times, 
#one record was altered (path and digits).

出力例(1):

src/path/to/code.test.js => [13|31:415 27|31:415 55|31:415 69|31:415]
src/path/to/othercode.test.js => 41|32:416

数の先行列を取得するには、後のコードをEND次に置き換えます。

for %h.kv -> $k,$v {say $v.elems, "\t", $k => $v};

出力例(2):

4   src/path/to/code.test.js => [13|31:415 27|31:415 55|31:415 69|31:415]
1   src/path/to/othercode.test.js => 41|32:416

[注:ハッシュが関連している場合、say通常は矢印で区切られた出力が生成されます。上記で簡単に最終コマンドを]に変更すると、key => valueタブで区切られたKey-Value出力が得られます。sayput

https://docs.raku.org/言語/regexes#Tilde_for_nesting_structs
https://docs.raku.org/言語/hashmap
https://raku.org

関連情報