16초와 23초가 있는 경우 파일을 분할하는 Perl 코드입니다. 그리고 파일로 복사

16초와 23초가 있는 경우 파일을 분할하는 Perl 코드입니다. 그리고 파일로 복사

문자열 "16S" 및 "23S"를 검색하고 이 문자열이 포함된 부분을 두 개의 개별 파일로 추출하려는 파일이 있습니다.

입력 파일:

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.

두 번째 블록은 비어 있지만 패턴은 description및 로 시작하는 줄과 일치하며 계속해서 p명령줄에 제공된 정규식( )과 해당 줄을 일치시킵니다. 일치하는 부분이 있으면 일치하는 부분을 골라 파일명으로 사용합니다.

해당 단어로 시작하는 줄을 찾으면 세 번째 블록이 실행되고 start저장된 섹션 텍스트를 현재 줄로 설정하고 그 안에 저장된 이전 텍스트를 모두 삭제합니다. 그런 다음 스크립트의 시작 부분으로 이동하여 다음 입력 줄을 고려합니다.

마지막 블록은 파일의 다른 모든 줄에 대해 실행되고 현재 줄을 현재 저장된 섹션에 추가합니다.

답변2

<LF>//<LF>이를 레코드 구분 기호로 사용할 수 있다면 GNU를 사용하면 awk다음과 같을 수 있습니다.

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

관련 정보