2020년 2월 20일 목요일

특정 문자를 구분자로 하는 문자열의 효과적인 조작 방법

일루미나 시퀀싱 장비에서 생산된 raw fastq file은 밑줄 문자('_', underscore)를 구분자로 하여 몇 개의 필드가 연결된 이름이 붙는다. 여기에서 꼭 필요한 필드만을 취하여 보다 간결하고 읽기 쉬운 파일명으로 고치려면 어떻게 하면 좋을까? 다음의 간단한 사례를 보자.

$ VAR=1_2_3_4_5
$ echo $VAR
1_2_3_4_5
$ echo $(cut -d_ -f1,3,5 <<<$VAR)  #1번 방식
1_3_5
$ echo $(cut -d_ -f1,3,5 <(echo $VAR)) #2번 방식
1_3_5

1번이나 2번 방식 전부 결과는 같다. 2번 방식(process substitution)은 비교적 최근에 알게 되었다(링크). 이를 활용하면 반복문을 통해서 현재 디렉토리에 있는 fastq 파일의 이름을 일괄적으로 바꿀 수 있다. 다음은 실제 사례이다. 밑줄 문자를 경계로 하여 첫번째 필드와 네번째 필드(R1 or R2)만이 최종 파일 이름에 남는다.

$ ls *fastq.gz | while read f
> do
> mv $f $(cut -d_ -f1,4 <<<$f | sed 's/_R/_/').fastq.gz
> done

그러면 이를 조금 더 응용해 보자. 여러 미생물의 시퀀싱 샘플에 대하여 SPAdes 조립을 실시하여 현 위치에 각 샘플에 대한 spades 결과 디렉토리를 여러 개 갖고 있다고 가정하자. 각각의 하위에는 scaffolds.fasta라는 동일한 이름의 결과 파일이 존재한다. 후속 분석을 위하여 이를 꺼내어 한데 모으되, 파일 명에 샘플 이름이 반영되게 바꾸고 싶다면 어떻게 하면 좋을까? 어쩌면 예전에 블로그에 이미 그 해결 방안을 작성해 주었을지도 모른다. 중복이 될지도 모르겠지만 지금 작성하는 해결법이 더 '성숙한 방법'이라고 믿고 싶다.

원본 파일의 일반 명칭이 spades_sample1/scaffolds.fasta라고 가정하자. 이를 현 디렉토리에 spades_sample1_scaffolds.fasta라고 이름을 바꾸어 복사하려면 다음 스크립트를 활용하라. SPAdes 결과 디렉토리에는 k-mer의 크기를 달리하여 조립한 서브 디렉토리가 하위에 공존하므로, find를 통한 검색의 깊이(-mindepth 및 -maxdepth 옵션으로 설정)를 잘 조정해야 한다.

$ find spades_* -maxdepth 1 -name scaffolds.fasta | while read f
> do
> cp $f $(sed 's/\//_/' <<<$f)
> done

실용에 문제가 없는 스크립트이다. 좀더 복잡한 규칙으로 파일 명칭을 바꾸려면 do 블록 내 cp 명령어의 두번째 인수에 해당하는 명령어를 적절히 고치면 된다. tr, sed 등 알고 있는 명령어를 조합하고 몇 개의 pipe 처리를 해도 된다.

댓글 없음: