FASTQ와 표 파일, 열어 보지 않고 명령어로 확인할 수 있을까요? 분석가를 위한 리눅스 명령줄 기본기
목차
📌 이 글에서 알 수 있는 것
- 분석가가 GUI 대신 명령줄을 쓰는 이유
- 압축 FASTQ·TSV를 열지 않고 보고, 세고, 뽑는 기본 명령 20여 개
- 파이프·리디렉션, awk·sed 한 줄 명령, 여러 시료 일괄 처리
- 데이터를 지우거나 망가뜨리지 않는 안전 습관
🖥️ 왜 명령줄인가요?
오믹스 파일은 크고 많습니다. 시료 하나의 FASTQ가 수 GB이고, 분석 서버(HPC)는 보통 화면 없이 터미널로만 접속합니다. 스프레드시트에는 다른 위험도 있습니다. PubMed Central 논문의 보충 파일을 조사한 2021년 연구에서, 엑셀 유전자 목록이 있는 논문 11,117편 중 3,436편(30.9%)에서 유전자 이름이 날짜·숫자로 바뀐 오류가 발견됐습니다1.
명령줄은 원본을 건드리지 않고 읽고, 쓴 명령 자체가 처리 기록으로 남습니다. 2026년 생물학자용 Unix 교육과정도 less·head·gzip·wc·grep·cut을 3단계, 파이프·리디렉션·sort를 4단계 핵심 기술로 묶었습니다2. 이 글의 예시는 GNU 도구(리눅스 서버 기본) 기준입니다.
📂 둘러보기와 열어 보기
ls -lh raw/
pwd
less -S sample_sheet.tsv
head -n 8 sample.fastq
tail -n +2 sample_sheet.tsv
ls -l: 권한·크기·날짜를 길게 표시,-h: 크기를 K·M·G 단위로pwd: 지금 위치. 이 글의 명령은 모두 raw/와 results/가 있는 프로젝트 폴더에서 실행합니다(이동은cd 폴더,cd ..은 한 단계 위,cd ~는 홈)less -S: 긴 줄을 접지 않고 잘라 표처럼 보기, 좌우 화살표로 이동,q로 종료head -n 8: 앞 8줄(FASTQ 2리드),tail -n +2: 2번째 줄부터 출력(머리글 빼기)3- 자주 하는 실수: 큰 파일을
cat으로 열어 터미널이 멈춤. 먼저head나less로 봅니다.
모르는 옵션은 man sort나 sort --help로 그 자리에서 확인합니다.
압축 파일은 풀어서 저장하지 않고 흐름으로 읽습니다.
gzip -cd sample.fastq.gz | head -n 8
zless sample.fastq.gz
pigz -k -p 8 sample.fastq
gzip -c: 결과를 표준 출력(화면으로 나가는 기본 출력)으로 보내고 원본 유지,-d: 압축 해제.zcat은gunzip -c와 같습니다4zless: 압축 파일을 그대로 화면 단위로 보기pigz -p 8: 8개 스레드로 gzip 형식 압축. gzip처럼 끝나면 원본을 지우므로 원본을 남기려면-k를 붙입니다. 해제는 병렬화되지 않습니다5- 자주 하는 실수: macOS 기본
zcat은.Z파일을 찾아.gz에서 실패할 수 있습니다.gzip -cd를 쓰면 어디서나 됩니다.
🔗 파이프와 리디렉션
gzip -cd sample.fastq.gz 2> err.log | wc -l > lines.txt
echo "sample2 done" >> run.log
|: 앞 명령의 출력을 다음 명령의 입력으로>: 파일로 저장(이미 있으면 덮어씀),>>: 끝에 덧붙이기2>: 오류 메시지(표준 오류)만 따로 저장6- 자주 하는 실수: 입력 파일로 바로 다시 저장(
sort a.tsv > a.tsv). 셸이 먼저 파일을 비워 내용이 사라집니다. - 자주 하는 실수:
2>는 바로 앞 명령 하나에만 붙습니다. 파이프 끝에 붙이면 앞 명령(gzip)의 오류는 저장되지 않습니다.
🧰 텍스트 도구 다섯 가지
grep -c -w "TP53" genes.tsv
grep -v "^#" variants.vcf | head
cut -f 1,3 genes.tsv
tail -n +2 genes.tsv | sort -t $'\t' -k4,4n
cut -f 3 genes.tsv | sort | uniq -c
wc -l genes.tsv
grep -c: 일치하는 줄 수,-w: 단어 전체가 일치할 때만(TP53BP1은 빠지지만 하이픈이 붙은 TP53-AS1은 걸림. 열 값이 정확히 같은 줄은awk -F '\t' '$2 == "TP53"'),-v: 일치하지 않는 줄(여기서는 # 머리글 빼기)7cut -f: 열 번호로 뽑기. 기본 구분자가 TAB이라 TSV에 바로 쓰고, CSV는-d ','sort -k4,4: 4번째 열만 기준.-k4만 쓰면 4번째 열부터 줄 끝까지가 기준입니다.-n: 숫자 크기순(1e-10같은 지수 표기는-g),-t $'\t': TAB 구분(기본은 공백 경계라 값에 공백이 있으면 열이 밀림)uniq -c: 연속된 같은 줄을 개수와 함께 하나로. 붙어 있는 줄만 합치므로 반드시sort뒤에3wc -l: 줄 수(머리글 포함)- 자주 하는 실수:
sort순서는 로케일(언어 설정)에 따라 달라집니다. 파일끼리 비교할 정렬은LC_ALL=C sort로 고정합니다.
🧮 실전 한 줄 명령
FASTQ는 리드 하나가 4줄입니다. head -n 4로 보면 구조가 보입니다.
@read1 1:N:0:ACGT
GATTACAGATTACA
+
IIIIIHHHGG@@?#
- 1줄:
@로 시작하는 리드 이름, 2줄: 서열, 3줄:+구분 줄, 4줄: 염기별 품질 점수(문자 하나가 염기 하나)
그래서 리드 수는 줄 수를 4로 나눕니다.
echo $(( $(gzip -cd sample.fastq.gz | wc -l) / 4 ))
- 예를 들어 출력이
2500000이면 리드 250만 개. paired-end면 R1·R2가 같아야 합니다. - 자주 하는 실수:
grep -c '^@'로 세기. 품질 줄도 @로 시작할 수 있어, 리드 2개짜리 파일에서 3이 나오기도 합니다.
TSV에서 열 하나를 뽑아 범주별로 셉니다.
tail -n +2 genes.tsv | cut -f 3 | sort | uniq -c | sort -k1,1nr
- 머리글을 빼고 3번째 열(예: biotype)을 뽑아 범주별 개수를 많은 순으로 보여 줍니다. 예를 들어 출력이
19000 protein_coding이면 그 범주가 1만 9천 줄이라는 뜻입니다. -k1,1nr: 첫 열을 숫자 역순(r)으로
✂️ awk와 sed는 짧게
awk -F '\t' 'NR > 1 && $5 >= 30 {print $1}' table.tsv
awk -F '\t' 'NR > 1 {s += $2} END {print s}' counts.tsv
gzip -cd sample.fastq.gz | awk 'NR % 4 == 2 {print length($0)}' | sort -n | uniq -c
sed 's/^chr//' regions.bed
sed -n '1,4p' sample.fastq
-F '\t': TAB으로 열을 나눔,$1: 첫 열,NR: 지금까지 읽은 줄 번호,END: 다 읽은 뒤 실행8- 첫 줄: 머리글 제외, 5열이 30 이상인 줄의 1열 출력 / 둘째 줄: 2열 합계 / 셋째 줄: 리드 길이 분포
s/찾을것/바꿀것/: 줄마다 처음 일치한 것을 치환(전부는 끝에g),-n ... p: 지정한 줄만 출력9- 자주 하는 실수: 값이
NA인 칸은 문자열 비교가 돼 조건을 통과합니다.$5+0 >= 30처럼 숫자로 바꿔 비교합니다. - 자주 하는 실수:
sed -i(macOS는sed -i '')로 원본을 바로 고치기. 새 파일로 저장해 확인한 뒤 바꿉니다.
🔁 여러 시료를 한 번에
for fq in raw/*_R1.fastq.gz; do
s=$(basename "$fq" _R1.fastq.gz)
printf '%s\t%s\n' "$s" $(( $(gzip -cd "$fq" | wc -l) / 4 ))
done > read_counts.tsv
basename: 경로와 꼬리(_R1.fastq.gz)를 떼어 시료 이름만 남김printf '%s\t%s\n': 시료 이름과 리드 수를 TAB으로 이어 한 줄씩 출력. 결과는 시료별 리드 수 표- 자주 하는 실수: 일치하는 파일이 없으면 패턴 문자열이 그대로 들어가 표에
*와 0으로 된 가짜 행이 남습니다(종료 상태 0). 루프 앞에shopt -s nullglob을 둡니다. - 자주 하는 실수: 손상된 .gz도 잘린 리드 수가 그대로 표에 들어가고,
set -euo pipefail로도 멈추지 않습니다. 아래gzip -t검사를 먼저 돌립니다.
find raw -name '*.fastq.gz' -print0 | xargs -0 -n 1 -P 4 gzip -t
parallel -j 4 'gzip -cd {} | wc -l > results/{/.}.lines' ::: raw/*.fastq.gz
xargs -P 4: 동시에 4개 실행(기본 1),-n 1: 한 번에 파일 하나,-0:-print0과 짝지어 공백 있는 이름도 안전하게10gzip -t: 압축 파일 손상 검사(정상이면 아무것도 출력하지 않음)parallel -j 4: 작업 4개 동시,{}: 입력 파일,{/.}: 경로와 마지막 확장자를 뗀 이름(결과는 results/에 저장, 먼저mkdir -p results),:::뒤가 입력 목록- 논문 방법에 GNU parallel을 쓰면
parallel --citation이 보여 주는 판본별 정보로 인용합니다11. - 자주 하는 실수: 서버 코어보다 많이 띄우거나, 여러 작업이 한 파일에 동시에 써서 출력이 섞임
🛡️ 데이터를 지키는 안전 습관
#!/usr/bin/env bash
set -euo pipefail
outdir="results"
rm -rf -- "${outdir:?}/tmp"
md5sum -c md5sums.txt
chmod -R a-w raw/
set -e: 명령이 실패하면 멈춤,-u: 정의되지 않은 변수를 오류로,-o pipefail: 파이프 중간 실패도 실패로6- 이 블록은 파일(예:
check.sh)로 저장해bash check.sh로 실행합니다. 터미널에set -e를 직접 치면 이후 명령 하나만 실패해도 창이 닫히거나 접속이 끊깁니다. "$var": 큰따옴표가 없으면my sample.fastq.gz같은 이름이 두 개로 쪼개집니다. 파일 이름에는 처음부터 공백을 쓰지 않는 편이 좋습니다.${outdir:?}: 변수가 비어 있으면 멈춤. 비어 있는 변수로rm -rf "$outdir/tmp"이 돌면/tmp를 지우려 듭니다.md5sum -c: 받은 파일을 제공처의 체크섬 목록과 대조. 목록에 파일 이름만 있으면(cd raw && md5sum -c ../md5sums.txt).gzip -t는 압축 형식만 검사합니다chmod -R a-w: 원본 폴더를 모두 쓰기 금지로. 실수 방지일 뿐 백업은 아닙니다(되돌리기는chmod -R u+w).- 자주 하는 실수:
set -e를 믿고 확인을 생략.if조건,&&중간 명령, 명령 인자 속$(...)의 실패에는 멈추지 않습니다.
⚠️ 한계와 주의
- 도구 판본 차이: macOS의 sed·zcat·cat·sort는 BSD 계열이라 옵션이 다릅니다. 예시가 안 되면 리눅스 서버에서 돌리거나 GNU 도구를 설치합니다. macOS 기본 셸은 zsh라
shopt가 없고 일치하는 파일이 없는 패턴은 바로 오류가 납니다. 예시는bash를 실행한 뒤 따라 합니다. - pipefail과 head: 스크립트 안
gzip -cd 큰파일 | head는 head가 먼저 끝나면 gzip이 비정상 종료(141)로 기록돼 멈출 수 있습니다. - 윈도에서 만든 표: 줄 끝에 CR 문자가 붙어 마지막 열 비교가 틀어집니다.
cat -A(macOS는cat -vet)로 줄 끝의^M을 확인하고,tr -d '\r' < in.tsv > out.tsv로 지웁니다. - 복잡한 형식은 전용 도구로: BAM·VCF는 awk로 직접 파싱하지 말고 samtools·bcftools를 씁니다(7·8편). 정렬·변이 호출은 3편, 발현 분석은 12편에서 다룹니다.
🏛️ 지금 어디까지 왔나
- 교육: 2026년 PLoS Comput Biol 논문은 생물학자를 위한 5단계 Unix 교육과정과, 브라우저 안 터미널로 설치 없이 실습하는 Sandbox.bio 튜토리얼을 공개했습니다2.
- 한국: 국내 대학·기관의 명령줄 교육과정이나 공용 분석 서버 현황은 확인하지 못했습니다.
🧪 연구자 노트
- 명령을 외우기보다
head,less로 파일을 먼저 열어 보는 습관이 중요합니다. 분석 오류의 상당수는 파일 형식이나 열 순서를 확인하지 않아서 생깁니다.rm과 덮어쓰기(>)는 되돌릴 수 없습니다. 원본 데이터 폴더는 읽기 전용으로 두고, 결과는 다른 폴더에 쓰세요.
🙋 그래서 나에게는? — 실습 전 체크리스트
- 원본 FASTQ를 별도 폴더에 두고
md5sum -c로 대조한 뒤chmod -R a-w로 잠갔다 - 리눅스 서버인지 macOS인지, GNU 도구인지 확인했다
- 큰 파일은
head·less -S·gzip -cd ... | head로 먼저 봤다 - 리드 수는 줄 수÷4로 세고 R1·R2를 대조했다
- 스크립트 첫 줄에
set -euo pipefail을 넣고 변수를 큰따옴표로 감쌌다 - 쓴 명령을 스크립트나 기록 파일로 남겼다
⚠️ 이 글은 의학적 조언이 아니며, 특정 제품을 권하지 않습니다. 실제 환경에서는 기관 서버의 사용 규칙과 SOP를 우선하세요.
❓ 자주 묻는 질문
Q. 윈도 PC만 있는데 따라 할 수 있나요? A. WSL(윈도 안의 리눅스 환경)을 쓰거나 기관 리눅스 서버에 접속하면 됩니다. 설치가 어렵다면 Sandbox.bio처럼 브라우저 안 터미널로 먼저 연습할 수 있습니다2.
Q. awk와 Python 중 무엇을 배워야 하나요? A. 열 뽑기·합계·조건 필터처럼 한 줄로 끝나는 일은 awk가 빠릅니다. 여러 단계 계산이나 통계·그림이 필요하면 Python이나 R로 넘어가는 편이 낫습니다(10편).
Q. 명령이 잘 돌았는지 어떻게 확인하나요?
A. echo $?로 직전 명령의 종료 상태를 봅니다(0이면 성공). 파이프는 마지막 명령의 상태만 보여 주므로, 앞 명령까지 보려면 bash에서 echo "${PIPESTATUS[@]}"를 쓰거나 set -o pipefail을 켭니다. 오류 로그(2>로 저장한 파일)도 함께 확인합니다.
📚 오믹스 기술 시리즈
- 1편 WGS 플랫폼 비교
- 2편 WGS 커버리지·깊이 설계
- 3편 WGS 데이터 처리와 QC
- 4편 WGS vs WES vs 패널
- 5편 리눅스 명령줄 기본기 (이 글)
- 6편 분석 환경 만들기
- 7편 FASTQ·BAM 실전
- 8편 VCF·BED 실전
- 9편 워크플로 관리
- 10편 R과 Python
- 11편 RNA-seq 실험 설계
- 12편 RNA-seq 데이터 분석
- 13편 small RNA-seq 실험 설계
- 14편 small RNA-seq 데이터 분석
참고
Abeysooriya M 외. Gene name errors: lessons not learned. PLoS Comput Biol 2021;17:e1008984. doi:10.1371/journal.pcbi.1008984 ↩︎
Khamvongsa-Charbonnier L 외. Training biologists in Unix command-line skills: from curriculum to interactive online tutorials. PLoS Comput Biol 2026;22:e1014133. doi:10.1371/journal.pcbi.1014133 ↩︎ ↩︎ ↩︎
GNU coreutils 9.11 매뉴얼 페이지(sort, uniq, cut, head, tail, wc; 2026-11-06 접속) — man7.org ↩︎ ↩︎
GNU gzip 1.14 매뉴얼 페이지(gzip, zless; 2026-11-06 접속) — manpages.debian.org ↩︎
Adler M. pigz 매뉴얼(2023-08-19판, 2026-11-06 접속) — zlib.net/pigz ↩︎
GNU Bash 5.3 매뉴얼 페이지(set 내장 명령·리디렉션; 2026-11-06 접속) — man7.org ↩︎ ↩︎
GNU parallel 20261022 문서(–citation; 2026-11-06 접속) — gnu.org; Tange O. GNU Parallel 2018. Zenodo; 2018. doi:10.5281/zenodo.1146014 ↩︎