Bash: 중복 항목을 감지하고 번호를 매기는 중첩된 while 루프

Bash: 중복 항목을 감지하고 번호를 매기는 중첩된 while 루프

그래서 저는 유전자 제목이 적힌 텍스트 파일을 가지고 있는데, 같은 종에도 다른 유전자 서열이 있습니다. 그래서 헤더(headers.txt)를 추출해서 다른 파일( uniqueheaders.txt)에 복사했습니다. 에서 중복 항목을 모두 제거했습니다 uniqueheaders.txt.

루프에서 행을 읽은 다음 uniqueheaders.txt루프에서 읽어 headers.txt중복을 확인하려고 합니다. 이 if문은 중복을 감지하고 카운터를 증가시켜 헤더에 추가합니다. 그러면 headers.txtFASTA 파일에 다시 삽입할 수 있도록 모든 헤더에 번호가 지정됩니다 . 내 코드는 다음과 같습니다.

while IFS= read -r uniqueline
do
    counter=0
    while IFS= read headline
    do
        if [ "$uniqueline" == "$headline" ]
        then
            let "counter++"
            #append counter to the headline variable to number it.
            sed "$headline s/$/$counter/" -i headers
        if
    done < headers.txt
done < uniqueheaders.txt

문제는 단말기에서 자꾸 오류가 난다.

sed: -e expression #1, char 1: unknown command: 'M'

그리고

sed: -e expression #1, char 2: extra characters after command

두 파일 모두 고유한 헤더 이름을 포함합니다.

Mus musculus
Homo sapiens
Rattus norvegicus

sed이 오류를 방지하려면 명령을 어떻게 수정해야 합니까 ? 더 좋은 방법이 있나요 bash?

입력 예(유전자 서열은 실제로 많은 줄의 패턴을 차지하지 않습니다.)**** 유전자 서열이 하나의 파일에 모두 들어 있습니다.

Mus musculus 
MDFJSGHDFSBGKJBDFSGKJBDFS
NGBJDFSBGKJDFSHNGKJDFSGHG
Rattus norvegicus
SNOFBDSFNLSFSFSFSJFJSDFSD
Mus musculus
NJALDJASJDLAJSJAPOJPOASDJG
DSFHBDSFHSDFHDFSHJDFSJKSSF

원하는 출력:

Mus musculus1 
MDFJSGHDFSBGKJBDFSGKJBDFS
NGBJDFSBGKJDFSHNGKJDFSGHG
Rattus norvegicus
SNOFBDSFNLSFSFSFSJFJSDFSD
Mus musculus2
NJALDJASJDLAJSJAPOJPOASDJG
DSFHBDSFHSDFHDFSHJDFSJKSSF

답변1

awk나는 기본 기반 솔루션을 생각해 냈습니다.

헤더 파일에는 특정 ID가 없으므로 고유한 헤더가 포함된 헤더 파일을 먼저 읽은 다음 실제 시퀀스 파일을 두 번 읽는 "2파일 2단계" 접근 방식을 수행합니다. 파일이 인쇄됩니다. 여러 번 나타나는 헤더에는 명확성을 위해 번호가 지정됩니다.

awk 'NR==FNR{tot[$0]=0;next}
     !final {if ($0 in tot) {tot[$0]++};next}
      final && ($0 in tot) {if (tot[$0]>1) $0=$0 (++cnt[$0])}1' uniqueheaders.txt sequence.txt final="1" sequence.txt 
  • NR전역 라인 카운터가 파일별 라인 카운터와 같으면 처리 FNR할 첫 번째 파일(여기 uniqueheaders.txt)에 있다는 것을 알 수 있습니다. 그런 다음 배열에 제목을 "로그"하면 tot나중에 제목이 나타나는 총 횟수가 저장됩니다.
  • 우리는 얼마나 많은 헤더 라인과 시퀀스 파일 라인이 있는지 모르기 때문에 라인 카운터 변수는 우리가 어떤 파일에 있는지 더 이상 식별하는 데 도움이 되지 않습니다(적어도 특정 awk구현에 의존하고 싶지 않은 경우). . 1한 번만 나타나는 헤더에 a 를 추가하는 것을 억제하려면 "시퀀스 파일"(예제 입력)을 두 번 처리해야 하기 때문에 (참조이 Q&A는 토론을 위한 것입니다), 매개변수로 두 번 선언하지만 awk두 번째 패스에 대한 플래그를 설정합니다.final
  • 시퀀스 파일의 첫 번째 단계( final아직 설정되지 않음)에서는 헤더가 포함된 행만 살펴보고(즉, $0전체 행이 배열의 인덱스에 있음 tot) 총 발생 횟수 카운터를 증가시킵니다.
  • 시퀀스 파일의 두 번째 패스( final현재 로 설정됨 1)에서 우리는 일반적으로 모든 라인을 인쇄하지만, 헤더 라인인 라인(역시 $0배열의 인덱스로 표시됨 tot)에서는 카운터(배열에 저장됨) cnt를 추가합니다. 우리는 이 헤더( )에 대한 중복이 있다는 것을 알고 있습니다 tot[$0]>1.

노트특정 기준(예: 빈 줄로 구분된 모든 유전자 서열)에 따라 시퀀스 파일의 헤더 라인을 선택할 수 있다면 외부 파일이 필요하지 않으며 uniqueheaders.txt단일 호출로 모든 작업을 수행할 수 있습니다.awk

관련 정보