2022년 10월 7일 금요일

dc 명령어를 이용하여 연속적인 숫자를 범위로 전환하기

MSA(multiple sequence alignment)를 처리하여 특정 조건을 만족하는 컬럼의 위치를 출력할 때가 있다. 예를 들어 trimAl이나 ClipKIT를 사용하여 MSA로부터 gap이 일정 기준 이하인 컬럼을 전부 뽑아내어 파일로 출력하게 만드는 일을 뜻한다. 컬럼의 연이어 존재한다면, 이를 병합하여 범위로 만들면 쓸모가 많다. 예를 들어 MSA로부터 대표적인 서열을 하나 추출한 다음, 컬럼 위치 정보를 사용하여 서열 단편을 끄집어 내는 것이다.

이 과정에서는 다음과 같은 전환 작업이 필요하다. 왼쪽에 보인 숫자는 쉼표가 아니라 new-line character를 경계로 하여 배열될 수도 있다.

1, 2, 3, 5, 6, 8, 10... -> 1-3, 5-6,  8, 10...

SARS-CoV-2의 검출을 위한 프라이머 설계 및 검증 연구(올해 출판한 논문 링크)에서는 별로 영리하지 못한 Perl script를 작성하여 인접한 숫자를 병합하는 작업을 했었다. 최근 들어서 Influenza A virus에 대하여 비슷한 일을 하게 되니 이전보다는 더욱 효율적인 방법을 찾고 싶었다. 구글을 검색해 보면 대부분 awk를 이용한 짤막한 스크립트로 이를 구현하고 있었다. 이는 너무 평이해 보여 뭔가 색다른 방법이 없을까 찾아보니... 사실은 외장 하드디스크드라이브에 보관한 예전 스크립트를 찾기가 귀찮아서 새로운 시도를 해 본 것이었다.

[Stack Exchange] How to collapse consecutive numbers into ranges?

가장 위에 달린 답변은 다음과 같았다.

출처: StackExchage

순간 내 눈을 의심하였다. 이게 뭐지? 처음 보는 명령어(스크립트?)였다. 첫 줄을 보니 데이터 파일 $1에 대하여 dc라는 명령어를 수행하고, 상세한 작동은 뒤의 따옴표('...') 안에 포함된 코드에 따르는 것처럼 보였다. 도저히 내가 이해할 수 있는 수준의 것이 아니다.

dc라는 것은 산술식을 계산하는 명령어로서 desktop calculator의 약자라고 한다. 얼핏 보면 무척 불친절한 탁상용 계산기처럼 보인다. 이는 dc가 일종의 postfix notation을 사용하는 계산기이므로 숫자를 입력한 다음에 연산자를 넣는 방식을 취하기 때문이다. 그렇다 하더라도 각괄호가 난무하는 계산식은 도저히 이해를 할 수가 없다. 하지만 데이터 파일을 만들어서 실제로 위 스크립트를 돌리면 결과가 잘 나오니 믿고 쓸 수밖에...

텍스트 파일의 라인 순서를 뒤집어서 출력하는 명령어가 무엇인지 아는가? 복잡하게 스크립트를 짤 필요가 없이 tac 명령어 한 방이면 끝난다. 왜 tac인가? cat을 뒤집어 놓은 것이므로!



댓글 없음: