2

もう一度いくつかの質問をします。次の形式のファイルがあります。

>seq1
123 234 56
167 332 22
23 456 098
>seq2
123 234 56
167 332 22
23 456 098

次のように、各 >seq# を保存するファイルが必要です。

ファイル 1:

>seq1
123 234 56
167 332 22
23 456 098

ファイル 2:

>seq2
123 234 56
167 332 22
23 456 098

私は perl スクリプトを使用できましたが、perl の知識を増やすためだけに、perl ワンライナーを使用してこれを行う方法を考えていました。

ありがとう!!

4

2 に答える 2

2

Jonathan's answerを見て、新しい回答を投稿するのに十分奇妙なものを思いつきました。これは、適切なコードではなく、演習の例 (おそらく難読化) と見なす必要があることを付け加えておきます。ソリューションの功績はすべて Jonathan にあります。また、これは一番下で説明されているように、危険な解決策です。

perl -ple 'open STDOUT, $_' yourfile.txt

これは、 Jonathanが発見>seq1した古い 2-argumentopenで使用されるで始まる行に依存しています。たとえば、書き込み用にファイルを作成 (上書き) して開きます。open $fh, ">seq1"seq1

同時に、有効な「モード」記号 ( 、 など) を持たない行は、<デフォルト>で読み取り用に開かれ|ます。123 234 56ディレクトリを使用するopenと、サイレントに失敗し、以前に開いたSTDOUTファイル ハンドルを維持することができます。

-lオプションを使用するchomp $_ことで、openが失敗しないようにする必要も、印刷に改行を追加する必要もありません。同時に、-pオプションはwhileループの作成と印刷を処理します。

出力はデフォルトで にSTDOUT行われるため、ファイル ハンドルを再度開くだけSTDOUTで、残りは入力ファイルの内容によって処理されます。

このワンライナーの完全なコードと、どの部分がどのスイッチから来ているかを示すコメント:

BEGIN { $/ = "\n"; $\ = "\n"; }    # -l, gives newlines to print
while (<>) {                       # -p 
    chomp $_;                      # -l
    open STDOUT, $_;               # our code
}
continue {
    print STDOUT $_;               # -p
}

注:このコードは、コマンドの全機能を解放しopenます。この場合、ファイル システムで任意のコマンドを実行できるようになるため、危険です。これは、2 引数オープンの使用を許可することの副作用です。

于 2013-07-19T02:05:13.007 に答える
2

これは、仕事をするかなり最小限のスクリプトです。

use strict;
use warnings;
my $fh = *STDOUT;

while (<>)
{
    chomp;
    if (m/^>/)
    {
        close $fh;
        open $fh, $_ or die "Failed to open $_";
    }
    print $fh "$_\n";
}

行は、最初の行my $fh = *STDOUT;の前に何かがある場合>file、それが標準出力にエコーされることを意味します。

これに基づいて、エラーを無視し、開いているファイルを閉じ、制限と読みやすさを考慮して、1 行にフラット化することができます。

perl -e 'while(<>){chomp;open$f,$_ if(m/^>/);print$f "$_\n";}'

でも、それをお勧めすることはできませんでした。(はい、両方のブランクが必要です。)

于 2013-07-19T00:45:14.897 に答える