2020년 3월 31일 화요일

텍스트 파일을 위치 기준으로 자르기(cut 명령어 사용)

KEGG Pathway 정보를 활용할 일이 생겼다. 5자리 숫자의 pathway 번호와 그 이름이 간결하게 텍스트 파일로 정리된 곳이 있다면 참으로 좋겠지만, 내 상식 수준에서는 https://www.kegg.jp/kegg/pathway.html의 내용을 마우스로 긁어서 가져오는 것 말고는 마땅한 방법을 찾지 못하였다. Subscription 기반으로 바뀐 다음부터는 KEGG DB를 적극적으로 이용하지를 않았으니 말이다.

텍스트를 복사해 놓으니 이런 꼴이다. 에휴...

012102-Oxocarboxylic acid metabolism
01212Fatty acid metabolism
01230Biosynthesis of amino acids

앞에서부터 다섯자리의 숫자가 끝난 다음에 탭을 집어넣으면 좋겠는데, 이를 위해서 스크립트를 짜자니 너무 성가시고, vim에서 치환 기능을 잘 쓰면 될 것도 같은데 방법이 잘 찾아지지 않는다. Perl에서 치환을 위해 쓰는 정규표현식과 vim에서 쓰는 것이 완벽하게 호환되지는 않는다. 그리고 vim에서 복잡한 검색 및 치환을 하는 데에는 익숙하지가 않다.

paste 명령어를 위치 기준으로 활용할 수는 없을까? cut -c 6-라고 입력하면 여섯번째 캐릭터부터 끝까지만 선택하여 출력하는 것이라고 한다. 그러면 라인의 처음부터 다섯번째 캐릭터까지를 선택하려면? 상상력을 발휘해 보자. cut -c -5가 된다. 말 그대로 5번째와 6번째 캐릭터 사이를 칼로 썰듯이 파일 전체를 두 조각으로 자르는 것이다.

그러면 이 명령어를 paste와 조합하면 되겠다. 위에 보인 내용이 infile.txt에 들어있다고 가정하자.

$ paste <(cut -c -5 infile.txt) <(cut -c 6- infile.txt) > outfile.txt

그렇지!  cut도 그렇지만 paste는 정말로 신비롭고도 유용한 명령어이다.  명령행 인수를 만들기 위해 파일(infile) 안의 목록을 쉼표로 구분하여 한 줄로 붙여야 할 경우가 있다. 이럴 때 $(paste -sd, infile)라는 표현이 얼마나 유용한지는 설명할 필요조차 없다. paste - - - < file은 또 어떠한가?

요즘은 업무를 위해 점점 저수준의 유틸리티나 bash 자체의 기능을 활용하는 일이 많아지고 있다. 간결하고 효율적이며 심지어 아름답기까지 하기 때문이다. 또한 치매 예방에도 좋다고 믿는다...

댓글 없음: