2

慣用的な Perl 6 を使用してこれを行いたいと思います。

ノイズの多い出力ファイルに埋め込まれた素晴らしい連続したデータの塊を見つけました。

Cluster Uniqueヘッダー行から始まり、それに続くすべての行を、最初に出現する空の行まで (ただし、それを含まない)単純に印刷したいと思います。ファイルは次のようになります。

</path/to/projects/projectname/ParameterSweep/1000.1.7.dir> was used as the working directory.
....

Cluster Unique Sequences    Reads   RPM
1   31  3539    3539
2   25  2797    2797
3   17  1679    1679
4   21  1636    1636
5   14  1568    1568
6   13  1548    1548
7   7   1439    1439

Input file: "../../filename.count.fa"
...

解析したいものは次のとおりです。

Cluster Unique Sequences    Reads   RPM
1   31  3539    3539
2   25  2797    2797
3   17  1679    1679
4   21  1636    1636
5   14  1568    1568
6   13  1548    1548
7   7   1439    1439
4

2 に答える 2

6

ワンライナー版

.say if /Cluster \s+ Unique/ ff^ /^\s*$/ for lines;

英語で

フレーズを含む once から始まりCluster Unique、次の空行の直前まで、入力ファイルからすべての行を出力します。

コメント付きの同じコード

.say                    # print the default variable $_
if                      # do the previous action (.say) "if" the following term is true
/Cluster \s+ Unique/    # Match $_ if it contains "Cluster Unique"
ff^                     # Flip-flop operator: true until preceding term becomes true
                        #                     false once the term after it becomes true
/^\s*$/                 # Match $_ if it contains an empty line
for                     # Create a loop placing each element of the following list into $_
lines                   # Create a list of all of the lines in the file
;                       # End of statement

拡大版

for lines() {
    .say if (
        $_ ~~ /Cluster \s+ Unique/  ff^  $_ ~~ /^\s*$/
    )
}
  • lines()<>perl5のようです。コマンド ラインにリストされた各ファイルの各行は、一度に 1 つずつ読み取られます。これはforループしているため、各行はデフォルト変数に配置されます$_
  • say改行も追加することを除いて、print に似ています。開始で書かれたとき.、それはデフォルト変数に直接作用します$_
  • $_はデフォルトの変数で、この場合、ファイルの 1 行が含まれます。
  • ~~$_正規表現と比較する一致演算子です。
  • //2 つのスラッシュの間に正規表現を作成する
  • \s+1 つ以上のスペースに一致
  • ffフリップフロップ演算子です。その左側の式が false である限り、false です。その左側の式が真と評価されたときに真になります。その右側の式が真になると偽になり、再び真として評価されることはありません。この場合、^ff^代わりにを使用するとff^、ヘッダーは出力に含まれません。
  • ^前(または後)に来ると、その左(または右)の式が真になる繰り返しも偽になるようffに修正します。ff
  • /^\*$/空行にマッチ
    • ^文字列の先頭に一致
    • \s*0 個以上のスペースに一致
    • $文字列の末尾に一致

ちなみに、Perl 5 のフリップフロップ演算子は..、スカラー コンテキストの場合です (リスト コンテキストの範囲演算子です)。もちろん、その機能は Perl 6 ほど豊富ではありません。

于 2015-03-20T22:42:05.523 に答える
3

慣用的な Perl 6 を使用してこれを行いたいと思います。

Perlでは、ファイル内のチャンクを見つける慣用的な方法は、ファイルを段落モードで読み取り、目的のチャンクが見つかったらファイルの読み取りを停止することです。10 GB のファイルを読み取っていて、チャンクが見つかった場合ファイルの先頭にある場合、ファイルの残りの部分を読み続けるのは効率的ではありません。

Perl 6 では、次のように一度に 1 つの段落を読むことができます。

my $fname = 'data.txt';

my $infile = open(
    $fname, 
    nl => "\n\n",   #Set what perl considers the end of a line.
);  #Removed die() per Brad Gilbert's comment. 

for $infile.lines() -> $para {  
    if $para ~~ /^ 'Cluster Unique'/ {
        say $para.chomp;
        last;   #Quit reading the file.
    }
}

$infile.close;

#    ^                   Match start of string.
#   'Cluster Unique'     By default, whitespace is insignificant in a perl6 regex. Quotes are one way to make whitespace significant.   

ただし、perl6 rakudo/moarVM関数内では引数が正しくopen()読み取られないnlため、現在は段落モードを設定できません。

また、次のような悪い慣習と見なされるイディオムもあります。

  1. if ステートメントを後置しsay 'hello' if $y == 0ます。

  2. $_コード内の暗黙の変数に依存する、例えば.say

したがって、フェンスのどちら側に住んでいるかにもよりますが、これはPerlでは悪い習慣と見なされます。

于 2015-03-22T03:25:20.307 に答える