Appendix A — Linux Cheatsheet for Viromics
A scannable quick reference for the commands used most often across this book. Copy, adapt, and keep it open in a second terminal. Commands are grouped by task so you can jump straight to what you need.
Preview before you overwrite or delete. Run a ls, head, or a --dry-run first, and only then commit to the real command. Most lost-data disasters come from a hasty rm or a redirect (>) onto the wrong file.
A.2 Files and folders
mkdir -p raw_reads trimmed_reads reports # -p makes parents, no error if present
cp -r results results_backup # -r copies folders
mv old_name new_name # rename or move
rm file # delete a file (no undo)
rm -r folder # delete a folder and its contents
ln -s /big/disk/db databases # symlink a large DB into the project
find . -name "*.fastq.gz" -size +1G # find large FASTQ filesA.3 Viewing and inspecting
head -n 20 file.tsv # first 20 lines
tail -n 20 file.tsv # last 20 lines
tail -f logs/run.log # follow a log live (Ctrl-C to stop)
less -S table.tsv # page a wide table without wrapping (q to quit)
wc -l file.tsv # count lines
zcat reads.fastq.gz | head # peek inside a gzip file without unzipping
column -t -s $'\t' file.tsv # pretty-print a TSVA.4 Text processing (grep, awk, sed, cut, sort, uniq)
grep -c "^>" contigs.fa # count sequences in a FASTA
grep -v "^#" table.tsv # drop comment/header lines
grep -i "virsorter" logs/*.log # case-insensitive search across logs
cut -f1,3 table.tsv # keep columns 1 and 3
cut -f1 table.tsv | tail -n +2 # column 1, minus the header
sort -k2,2 -t$'\t' table.tsv # sort by column 2 (tab-separated)
sort -k5,5nr table.tsv # sort by column 5, numeric, descending
sort file.txt | uniq -c | sort -nr # count and rank unique values
awk -F'\t' 'NR>1 && $4=="High-quality"' checkv.tsv # filter rows by a column value
awk -F'\t' '$2>=10000' lengths.tsv # keep contigs >= 10 kb
awk -F'\t' '{sum+=$2} END{print sum}' lengths.tsv # sum a column
sed 's/old/new/g' file.txt # replace text (prints to screen)
sed -i 's/old/new/g' file.txt # replace in place (edits the file)
sed 's/ .*//' contigs.fa # keep only the first word of FASTA headers
tr ',' '\t' < file.csv > file.tsv # convert commas to tabs
paste a.txt b.txt # merge two files column-wiseA.5 FASTA and FASTQ with seqkit
seqkit stats *.fastq.gz # N, length stats, N50
seqkit seq -m 1000 contigs.fa > contigs_min1kb.fa # keep sequences >= 1 kb
seqkit grep -f ids.txt contigs.fa > selected.fa # extract by ID list
seqkit grep -v -f drop.txt contigs.fa > kept.fa # exclude an ID list
seqkit fx2tab -n -l contigs.fa > lengths.tsv # name + length table
seqkit rmdup -s contigs.fa > dedup.fa # remove exact duplicates
seqkit subseq -r 1:5000 genome.fa # slice a region
seqkit sort -l -r contigs.fa > by_length.fa # sort by length, longest first
seqkit replace -p ".*" -r "ctg_{nr}" contigs.fa # renumber headers cleanlyA.6 Conda and mamba
conda env list # list environments
mamba create -n viromics-core -c conda-forge -c bioconda fastqc fastp multiqc
conda activate viromics-core
mamba install -c conda-forge -c bioconda seqkit # add a tool to the active env
conda deactivate
conda env export --no-builds > env.yml # record an environment
mamba env create -f env.yml # rebuild it elsewhere
conda config --set channel_priority strict # avoids many solver conflictsmamba, and one job per environment
mamba resolves dependencies far faster than the classic conda solver. When two heavy tools conflict, do not fight the solver — give each its own environment (virsorter2, genomad, checkv, …) and switch between them.
A.7 Bash scripting
cat > run.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail # stop on errors, unset vars, and failed pipes
THREADS=12
for r1 in trimmed_reads/*_R1.fastq.gz; do
sample=$(basename "$r1" _R1.fastq.gz)
echo ">> processing $sample"
# your command here, using "$sample" and "$THREADS"
done
EOF
chmod +x run.sh
bash run.sh 2>&1 | tee logs/run.log # run and save all output to a logHandy building blocks:
VAR="value"; echo "$VAR" # set and use a variable
export VIROME_DB=~/databases # export so child processes see it
sample=$(basename "$path" .fastq.gz) # strip a directory and suffix
for f in *.fa; do echo "$f"; done # loop over files
cmd1 && cmd2 # run cmd2 only if cmd1 succeeds
cmd1 || echo "cmd1 failed" # fallback on failureA.8 Long-running jobs with tmux and screen
Assemblies, database downloads, and prediction runs can take hours. Detach them so a dropped SSH connection does not kill the job.
tmux new -s viromics # start a named session
# ... launch your long command inside it ...
# Detach: press Ctrl-b then d (the job keeps running)
tmux ls # list sessions
tmux attach -t viromics # reattach later
# screen equivalents:
screen -S viromics # start
# Detach: Ctrl-a then d
screen -ls # list
screen -r viromics # reattach
# Or run detached and log to a file:
nohup bash run_phase4_main_pipeline.sh > logs/phase4.log 2>&1 &A.9 Monitoring resources
htop # live CPU/RAM per process (q to quit; F9 to kill)
top # always-available fallback for htop
df -h # free disk space per filesystem
du -sh ~/viromics_course/* # which project folders are eating disk
du -sh databases/* # database sizes
free -h # free and used RAM
nproc # how many CPU threads are available
ls -lh out/*.bam # check output file sizes as a job progressesAssembly and mapping create large temporary files. Run df -h before you start a big job, and again if it fails with a write error — a full disk is the most common silent cause of a crashed assembly.