2022년 5월 27일 금요일

[Bash] 연속적인 숫자를 만들기

ZGA pipeline으로 바코드를 단 12개의 nanopore sequencing 결과물에 대한 de novo assembly를 마쳤다. FASTA file은 각 샘플에 대해서 다음의 하위 디렉토리에 존재한다.

zga_flye_barcode01/assembly/assembly.fasta

이를 전부 모아서 하나의 디렉토리(예: target/)에 모으고자 한다. FASTA 파일명이 전부 동일하므로 바코드 번호를 반영하여 변경해야 한다. 01부터 12까지 일련의 숫자를 생성하려면 seq 명령어를 쓰면 된다.

$ seq -w 1 12
01
02
03
..
12

'-w' 옵션은 출력하는 숫자 왼쪽에 자리채움용도의 '0'을 덧대는 용도로 쓰인다. seq는 기본적으로 '\n'을 separatorfh 사용하지만 다른 문자를 지정할 수도 있다. 다음의 명령어를 서로 비교해 보자. seq 명령어를 쓰지 않더라도 { .. } 구문을 사용하여 시작과 끝을 지정한 연속적인 숫자 혹은 문자를 출력할 수 있다.

$ seq -w -s ' ' 1 12
01 02 03 04 05 06 07 08 09 10 11 12
$ echo {01..12}
01 02 03 04 05 06 07 08 09 10 11 12
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

seq 명령어를 응용하여 지정된 하위 디렉토리에서 FASTA 파일을 찾은 뒤 각자 바코드명을 붙여 이름을 변경한 뒤 한 디렉토리에 모으는 코드는 다음과 같다. 변수를 좌우에 붙은 문자열과 명확히 구분하기 위해 ${i} 형태로 경계를 확실히하는 것도 좋은 습관일 것이다.

$ mkdir target
$ for i in $(seq -w 01 12)
> do
> find zga_flye_barcode$i -name assembly.fasta -exec cp {} target/barcode$i.assembly.fasta \;
> done
$ ls target
barcode01.assembly.fasta  barcode04.assembly.fasta  barcode07.assembly.fasta  barcode10.assembly.fasta
barcode02.assembly.fasta  barcode05.assembly.fasta  barcode08.assembly.fasta  barcode11.assembly.fasta
barcode03.assembly.fasta  barcode06.assembly.fasta  barcode09.assembly.fasta  barcode12.assembly.fasta새

샘플이 12개에 불과하니 cp 명령으로 하나씩 FASTA file의 이름을 바꾸어 가면서 원하는 위치에 복사를 해도 되지만, 실수의 가능성이 큰데다가 작업 기록을 남기기도 어렵다.

find 명령으로 찾아낸 FASTA file의 full path에서 중간에 위치한 특정 문자열을 꺼내어 최종 파일명의 일부를 삼고 싶다면? 어떤 규칙을 이용하여 string manipulation을 하면 될 수준의 일인가, 혹은 어떤 구분자(예를 들어 '/')로 나뉘는 필드 중 특정 위치의 것을 꺼내면 될 일인가에 따라서 해결 방법은 조금씩 달라진다. 예를 들어 다음과 같은 파일이 있다고 가정하자.

/data/project/131_Bacillus_from_human_gut_2021_Aug/00_seqs/03_nanopore/02_assembly/16S_rRNA_BS.fa

이렇게 긴 path에서 131_Bacillus..에 해당하는 중간 문자열을 꺼내고 싶다면? 이 path가 A라는 변수에 저장되어 있다고 가정하고 문제를 풀어보자. 방법은 간단하다.

$ cp $A $(cut -d/ -f4 <<< $A).fasta

'/'를 구분자로 하여 A 변수에 저장된 문자열을 나누는 경우 첫 번째 필드는 공백이 된다. 왜냐하면 A 변수에 저장된 문자열이 '/'로 시작하기 때문이다. 따라서 131_Bacillus를 꺼내려면 4번째 필드를 지정해야 한다('-f4'). 왜 -f 4라고 떼어서 쓰지 않고 -f4라고 붙여 쓰는가? 그래도 된다.

이 bash 구문에서 '<<<'의 의미를 정확히 이해하는 것은 쉽지 않다. 나도 이를 설명하려면 주저할 것이 뻔하다. 이론적으로 설명을 하기는 어렵지만, 알고 있으면 리눅스 작업 능률을 크게 올려주는 잡스런 지식이 무척 많이 있다. 이번 7월에 있을 미생물 유전체 분석 교육에서 수강생들에게 이를 어느 정도로 소개해야 하는지 고민이 된다.

댓글 없음: