unix: 파일에서 문자 10~80 가져오기

unix: 파일에서 문자 10~80 가져오기

줄로 구분된 텍스트가 포함된 파일이 있습니다.

GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG
GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC

여기에서 10에서 80까지의 문자를 추출하고 싶습니다.

TGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCCT

파일의 문자 수를 계산하는 방법을 찾았습니다.

  wc -m file

한 줄에 문자 수를 구하는 방법은 다음과 같습니다.

 awk '{print substr($0,2,6)}' file

하지만 10에서 80까지의 문자를 가져오는 방법을 찾을 수 없습니다.

개행 문자는 문자로 간주되지 않습니다.

어떤 아이디어가 있나요?

예, 이것은 완전한 게놈의 DNA입니다. 나는 다음을 사용하여 서로 다른 비계(이 경우 10과 11)가 포함된 fasta 파일에서 이 DNA를 추출했습니다.

 awk '/scaffold_10\>/{p=1;next} /scaffold_11/{p=0;exit} p'

궁극적으로 나는 지정된 스캐폴드에서 100~800자(또는 이와 유사한 문자)를 가져오는 간단한 명령을 원합니다.

편집: 질문은 여기서 계속됩니다.bash 스크립트 대신 gff2fasta를 사용하여 전체 게놈에서 부분 DNA 서열 얻기

답변1

$ cat file1
GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG
GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC

각 줄의 길이를 확인하세요.

$ awk '{print length,$0}' file1
70 GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
70 GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG
70 GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC

10-80자를 인쇄하세요.

$ awk '{print substr($0,10,70)}' RS= file1
TGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCC

입력에 빈 줄이 포함되어 있지 않다고 가정합니다( RS=활성화단락 모드여기서 각 레코드는 단락입니다(단락은 일련의 빈 줄로 구분됨). 이는 전체 파일이 메모리에 로드됨을 의미합니다.

답변2

파일에서 개행 문자를 어떻게 처리해야 하는지 알고 싶습니다. 이게 역할인가요?

10바이트를 빼내고 71바이트(A, C, T, G 및 개행 문자)를 인쇄하면 Sato Katsura의 솔루션이 가장 빠릅니다(이것은 GNU dd또는 Compatible 을 가정하고 status=none다음으로 대체합니다 2> /dev/null(이렇게 하면 오류 메시지도 숨겨집니다). ) 다른 구현과 함께):

 dd if=file bs=1 count=71 skip=9 status=none

줄바꿈을 건너뛰어야 하는 경우 다음 명령을 사용하여 필터링하세요 tr -d '\n'.

 tr -d '\n' < file | dd bs=1 count=70 skip=9 status=none

Fasta 헤더를 건너뛰어야 하는 경우:

 grep -v '^[;>]' file | tr -d '\n' | dd bs=1 count=70 skip=9 status=none

grep -v '^[;>]' file;또는 로 시작하는 모든 줄을 건너뛰라는 것을 나타냅니다 >.

답변3

바이트의 경우(따라서 이 예에서는 단일 바이트 문자의 경우도 해당):

dd bs=1 skip=9 count=71 < file 2> /dev/null

또는 GNU를 사용하면 더 효율적입니다 dd.

dd iflag=fullblock,skip_bytes,count_bytes skip=9 count=71 status=none < file

캐릭터의 경우 다음을 사용합니다 zsh.

{
  IFS= read -ru0 -k9 discard &&
    IFS= read -ru0 -k71 text &&
    printf %s $text
} < file

(파일이 80자 미만이면 아무것도 인쇄되지 않습니다.)

ksh93s 와 비슷한 bash옵션이 있지만 NUL 문자를 지원하지 않습니다.-Nzsh-k하나 bash는 오프로드 차량이다..

GNU 사용 awk:

awk -v RS='.{1}' -v ORS= 'NR>=10 {print RT}; NR == 80 {exit}'

우리가 사용하는 단일 문자는 정규식으로 간주되지 않습니다 .{1}..

또 다른 옵션은 문자당 4바이트의 UTF-32LE와 같이 문자당 고정된 수의 바이트(가능한 모든 문자 포함)를 갖는 문자 인코딩으로 변환하는 것입니다.

< file iconv -t UTF-32LE |
   dd bs=4 skip=9 count=71 2> /dev/null |
   iconv -f UTF-32LE

답변4

perl -l -0777pe '
   my($start, $stop) = qw/10 80/; $delta = $stop - $start--;
   (undef, $_, $a) = unpack "A${start}A${delta}A*";
   $_ .= $1 while length() - y/\n/\n/ < $delta and $a =~ /(.)/g;
'  scaffolded_file_10

관련 정보