16秒と23秒がある場合にファイルを分割するPerlコード。そしてファイルにコピー

16秒と23秒がある場合にファイルを分割するPerlコード。そしてファイルにコピー

文字列「16S」と「23S」を検索し、この文字列を含む部分を2つの別々のファイルに抽出したいファイルがあります。

入力ファイル:

start
description Human 16S rRNA
**some text**
**some text**
//
start
description Mouse 18S rRNA
some text
some text
//
start
description Mouse 23S rRNA
some text
some text
//

期待される出力: File1の16S:

start
description Human 16S rRNA
some text
some text
//

23S中のファイル2:

start
description Mouse 23S rRNA
some text
some text
//

私が使用するコード:

#! /usr/bin/perl   
# default output file is /dev/null - i.e. dump any input before
# the first [ entryN ] line.

$outfile='FullrRNA.gb';
open(OUTFILE,">",$outfile) || die "couldn't open $outfile: $!";

while(<>) {
  # uncomment next two lines to optionally remove comments (startin with
  # '#') and skip blank lines.  Also removes leading and trailing
  # whitespace from each line.
  # s/#.*|^\s*|\s*$//g;
  # next if (/^$/)

  # if line begins with 'start', extract the filename
  if (m/^\start/) {
    (undef,$outfile,undef) = split ;
    close(OUTFILE);
    open(OUTFILE,">","$outfile.txt") || die "couldn't open $outfile.txt: $!";
  } else {
    print OUTFILE;
  }
}
close(OUTFILE);

答え1

awk申し訳ありません。この問題を解決するためにPerlを使用します。

/^\/\// && file { file = file ".out";
                  print section ORS $0 >file;
                  file = "" }

/^description/ && match($0, p) && file = substr($0,RSTART,RLENGTH) {}

/^start/        { section = $0; next       }
                { section = section ORS $0 }

データに対して以下を実行します(p='expression'必要な部分を選択するために使用できます)。

$ awk -f script.awk p='16S|23S' file.in
$ ls -l
total 16
-rw-r--r--  1 kk  wheel   64 Aug 28 12:10 16S.out
-rw-r--r--  1 kk  wheel   56 Aug 28 12:10 23S.out
-rw-r--r--  1 kk  wheel  176 Aug 28 11:51 file.in
-rw-r--r--  1 kk  wheel  276 Aug 28 12:09 script.awk
$ cat 16S.out
start
description Human 16S rRNA
**some text**
**some text**
//
$ cat 23S.out
start
description Mouse 23S rRNA
some text
some text
//

セクション終了マーカー(で始まる行)を探し、出力//ファイル名(file)が空でない場合は、スクリプトの最初のブロックが実行されます。現在のファイル名に追加し.out、保存した部分をファイルに出力し、現在の入力行を出力します。次に変数を消去しますfile

2番目のブロックは空ですが、パターンdescriptionはとで始まる行と一致し、引き続きpコマンドラインで指定された正規表現()とその行を一致させます。一致する部分がある場合は、一致する部分を選択してファイル名として使用します。

その単語で始まる行が見つかると、3番目のブロックが実行され、保存されたセクションテキストが現在の行に設定され、startその中に保存されている以前のテキストがすべて削除されます。次にスクリプトの先頭に移動し、次の入力行を考慮します。

最後のブロックはファイル内の他のすべての行に対して実行され、現在の行を現在保存されているセクションに追加します。

答え2

<LF>//<LF>これをレコード区切り文字として使用できる場合は、GNUを使用するとawk次のようになります。

gawk -v 'RS=\n//\n' '
  {ORS=RT}; / 16S /{print > "file1"}; / 23S /{print > "file2"}' < file

関連情報