跳转至

Linux 命令行进阶:生信工程师必备技能

一句话说明:掌握 awk/sed 文本处理、进程管理、Shell 脚本编写和批量并行任务,让你从"会用 Linux"进阶到"高效用 Linux 做生信"。


为什么要学

你已经会 lscdcpgrep 这些基础命令了,但面试和实际工作中会遇到这些场景:

  • 一个 GFF 注释文件有 200 万行,需要提取所有基因的起止坐标——手动不可能,awk 一行搞定
  • 跑一个比对任务要 8 小时,关掉终端就断了——nohup/tmux 让任务后台持续运行
  • 50 个样本的 fastq 文件需要批量质控——Shell 循环 + GNU parallel 并行处理
  • 面试官问"如何查看服务器磁盘/内存/CPU 使用情况"——df/free/top 信手拈来

进阶命令行技能 = 生信工程师的"效率放大器"。下面按模块逐一讲解。


一、awk 详解:行列数据的瑞士军刀

1.1 基本语法

# awk 的基本结构:'模式 {动作}'
# awk 把每一行按分隔符拆成 $1, $2, $3...($0 是整行)
awk -F'\t' '{print $1, $3}' file.tsv
# -F'\t'  指定分隔符为 Tab(默认是空格)
# $1      第一列
# $3      第三列

1.2 核心概念

# NR = 当前行号(Number of Record)
# NF = 当前行的列数(Number of Field)
# FS = 字段分隔符(Field Separator)
# OFS = 输出分隔符(Output Field Separator)

# 打印行号和每行列数
awk -F'\t' '{print NR, NF}' data.tsv

# 跳过注释行(以 # 开头的行)
awk '!/^#/' file.gff

# BEGIN 在处理前执行,END 在处理后执行
awk 'BEGIN{sum=0} {sum+=$5} END{print "总和:", sum}' data.tsv

1.3 生信实例

# === 处理 GFF3 文件:提取所有基因的染色体、起止位置、基因名 ===
# GFF3 格式:chr \t source \t type \t start \t end \t score \t strand \t phase \t attributes
awk -F'\t' '$3=="gene" {print $1, $4, $5, $9}' annotation.gff3
# $3=="gene"  只保留第三列(类型)为 gene 的行
# $1          染色体
# $4, $5      起止坐标
# $9          属性列(含基因名)

# === 从 GFF3 属性列提取基因 ID ===
# 注意:match() 的第三参数(arr)是 gawk 扩展功能,需要用 gawk 而非 mawk
awk -F'\t' '$3=="gene" {
    match($9, /ID=([^;]+)/, arr);   # 用正则从第9列提取 ID= 后面的值
    print $1, $4, $5, arr[1]         # 输出 染色体 起始 终止 基因ID
}' annotation.gff3

# === 处理 BED 文件:计算每个区间的长度 ===
# BED 格式:chr \t start \t end \t name ...
awk -F'\t' '{
    len = $3 - $2;                    # 区间长度 = end - start
    print $0, len                     # 输出原行 + 长度
}' OFS='\t' regions.bed

# === 处理 TSV 文件:按条件过滤(如 p-value < 0.05 且 fold-change > 2) ===
awk -F'\t' 'NR==1 || ($6 < 0.05 && $4 > 2)' diff_expression.tsv
# NR==1       保留表头(第一行)
# $6 < 0.05   第6列 p-value 小于 0.05
# $4 > 2      第4列 fold-change 大于 2

# === 统计 FASTA 文件中每条序列的长度 ===
awk '/^>/ {if(name) print name, len; name=$0; len=0; next}
     {len += length($0)}
     END {print name, len}' sequences.fasta
# /^>/        匹配以 > 开头的行(序列名)
# length($0)  当前行的字符数(即序列长度)

# === 按染色体分组统计基因数量 ===
awk -F'\t' '$3=="gene" {count[$1]++}
     END {for(chr in count) print chr, count[chr]}' annotation.gff3
# count[$1]++    用关联数组按第1列(染色体)计数

二、sed 详解:流式文本编辑器

2.1 基本语法

# sed 的核心操作:s/查找/替换/标志
sed 's/old/new/'    file.txt   # 替换每行第一个匹配
sed 's/old/new/g'   file.txt   # 替换每行所有匹配(g = global)
sed -i 's/old/new/g' file.txt  # -i 直接修改原文件(慎用!先不加 -i 预览)

2.2 行操作

# 打印特定行
sed -n '5p' file.txt            # 只打印第5行(-n 抑制默认输出,p 打印)
sed -n '10,20p' file.txt        # 打印第10到20行

# 删除行
sed '1d' file.txt               # 删除第1行(d = delete)
sed '/^#/d' file.txt            # 删除所有以 # 开头的行(注释行)
sed '/^$/d' file.txt            # 删除所有空行

# 插入和追加
sed '1i\新的第一行' file.txt     # 在第1行前插入(i = insert)
sed '5a\追加的内容' file.txt     # 在第5行后追加(a = append)

2.3 生信实例

# === 替换 FASTA 文件中的染色体命名(如 chr1 → 1) ===
sed 's/^>chr/>/' genome.fasta
# ^>chr  匹配行首的 ">chr"
# >/     替换为 ">"(去掉 chr 前缀)

# === 去掉 GFF 文件的注释头(通常以 # 开头) ===
sed '/^#/d' annotation.gff3 > annotation_clean.gff3

# === 将 Windows 换行符(\r\n)转为 Unix 换行符(\n) ===
sed -i 's/\r$//' data.tsv
# \r$    行尾的回车符

# === 给 BED 文件的染色体列加 "chr" 前缀 ===
sed 's/^/chr/' regions.bed
# ^      行首,在行首插入 "chr"

# === 提取 FASTA 文件中指定范围的序列(如第100-200行) ===
sed -n '100,200p' large_genome.fasta > subset.fasta

# === 批量替换样本 ID(将旧 ID 替换为新 ID) ===
# 准备替换映射文件 mapping.txt,每行格式:old_id new_id
while read old new; do
    sed -i "s/${old}/${new}/g" sample_metadata.tsv  # 逐行读取并替换
done < mapping.txt

三、进程管理:让任务不中断

3.1 后台运行

# & 放到后台运行
bowtie2 -x index -1 R1.fq -2 R2.fq -S out.sam &
# 命令末尾加 & 就在后台执行,终端可继续用

# nohup:即使关闭终端,任务也不中断
nohup bowtie2 -x index -1 R1.fq -2 R2.fq -S out.sam > bowtie2.log 2>&1 &
# nohup        不挂断运行(no hang up)
# > bowtie2.log  标准输出写入日志
# 2>&1          标准错误也写入同一日志
# &             放到后台

# jobs:查看当前终端的后台任务
jobs
# fg %1    把编号1的后台任务调回前台
# bg %1    让暂停的后台任务继续运行

3.2 tmux:终端复用神器

# 安装
sudo apt install tmux              # Ubuntu/Debian

# 基本操作
tmux new -s bioinfo                # 创建名为 bioinfo 的会话
tmux ls                            # 列出所有会话
tmux attach -t bioinfo             # 重新连接到 bioinfo 会话
tmux kill-session -t bioinfo       # 关闭 bioinfo 会话

# tmux 内快捷键(先按 Ctrl+b,松开后再按功能键)
# Ctrl+b d    分离会话(detach,回到普通终端,任务继续跑)
# Ctrl+b c    新建窗口
# Ctrl+b n    切换到下一个窗口
# Ctrl+b %    左右分屏
# Ctrl+b "    上下分屏
# Ctrl+b 方向键  在分屏间切换

# 典型用法:SSH 到服务器,开 tmux,跑任务,detach 后关电脑,任务不断

3.3 screen(tmux 的老前辈,很多服务器预装)

screen -S mytask                   # 创建名为 mytask 的会话
screen -ls                         # 列出所有会话
screen -r mytask                   # 重新连接
# Ctrl+a d    分离会话(类似 tmux 的 Ctrl+b d)

3.4 进程查看与管理

# top:实时查看进程(按 q 退出)
top
# 常用操作:按 M 按内存排序,按 P 按 CPU 排序,按 1 查看各 CPU 核心

# htop:更友好的 top(彩色,支持鼠标)
htop                               # 需要安装:sudo apt install htop

# ps:查看进程快照
ps aux | grep bowtie2              # 查找含 bowtie2 的进程
# a    显示所有用户的进程
# u    显示详细信息
# x    包括无终端的进程

# kill:终止进程
kill 12345                         # 发送 SIGTERM 信号给 PID 12345(优雅终止)
kill -9 12345                      # 发送 SIGKILL 信号(强制杀掉,最后手段)
killall bowtie2                    # 杀掉所有名为 bowtie2 的进程

四、文件系统管理

4.1 磁盘与空间

# df:查看磁盘使用情况
df -h                              # -h 人类可读格式(GB/MB)
df -h /home                        # 查看 /home 所在分区

# du:查看目录/文件大小
du -sh *                           # 当前目录下每个文件/目录的大小
du -sh /home/pweaz/data/           # 某个目录的总大小
du -h --max-depth=1 /home/pweaz/   # 只看一级子目录的大小

# 找出占空间最大的文件
du -ah /home/pweaz/ | sort -rh | head -20
# -a     包含文件(不只目录)
# sort -rh  按大小逆序排列
# head -20  只看前20个

4.2 文件查找

# find:按条件查找文件
find /data -name "*.fastq.gz"                  # 查找所有 fastq.gz 文件
find /data -name "*.bam" -size +1G             # 查找大于 1GB 的 BAM 文件
find /tmp -mtime +30 -delete                   # 删除 30 天前修改的临时文件(慎用!)
find . -name "*.log" -exec gzip {} \;          # 把找到的 log 文件逐个压缩
find . -type f -name "*.fq" | wc -l            # 统计 fq 文件数量

4.3 软链接

# ln -s:创建软链接(类似 Windows 快捷方式)
ln -s /data/reference/hg38.fa ~/ref/hg38.fa
# 在 ~/ref/ 下创建一个指向原文件的链接,不占额外空间
# 生信常用:参考基因组、数据库文件太大,用软链接避免复制

ls -l ~/ref/hg38.fa                # 查看链接指向
# lrwxrwxrwx ... hg38.fa -> /data/reference/hg38.fa

4.4 权限管理

# chmod:修改文件权限
# 权限格式:rwx = 读(4) 写(2) 执行(1)
# 三组:文件主人(u) / 同组用户(g) / 其他人(o)
chmod 755 script.sh                # rwxr-xr-x(主人可读写执行,其他人可读可执行)
chmod +x script.sh                 # 给所有人加执行权限
chmod 644 data.tsv                 # rw-r--r--(主人可读写,其他人只读)

# chown:修改文件所有者(需要 sudo)
sudo chown pweaz:bioinfo data/     # 将 data/ 的主人改为 pweaz,组改为 bioinfo

五、网络工具

5.1 下载文件

# wget:下载文件(最常用)
wget https://example.com/hg38.fa.gz            # 直接下载
wget -c https://example.com/big_file.tar.gz    # -c 断点续传(大文件必备)
wget -O renamed.fa.gz https://example.com/file # -O 指定保存文件名

# curl:更灵活的下载/请求工具
curl -O https://example.com/data.tsv           # -O 用远程文件名保存
curl -L https://example.com/redirect           # -L 跟随重定向
curl -s https://api.example.com/gene/TP53      # -s 静默模式(常用于 API 请求)

5.2 文件传输

# scp:通过 SSH 复制文件
scp local_file.txt user@server:/remote/path/   # 上传文件
scp user@server:/remote/file.bam ./            # 下载文件
scp -r local_dir/ user@server:/remote/path/    # -r 递归复制整个目录

# rsync:增量同步(比 scp 更强大)
rsync -avz data/ user@server:/backup/data/
# -a    归档模式(保留权限、时间戳等)
# -v    显示详细信息
# -z    传输时压缩
# 只传输有变化的文件,适合大目录同步

rsync -avz --progress data/ user@server:/backup/
# --progress  显示传输进度

5.3 SSH 配置

# 生成 SSH 密钥对(免密登录)
ssh-keygen -t ed25519 -C "pweaz@example.com"
# 按回车使用默认路径,可设置密码(或留空)

# 复制公钥到服务器
ssh-copy-id user@server

# SSH 配置文件:~/.ssh/config(简化连接命令)
# 编辑 ~/.ssh/config 添加以下内容:
# Host bioserver                    # 别名
#     HostName 192.168.1.100        # 服务器 IP
#     User pweaz                    # 用户名
#     Port 22                       # 端口
#     IdentityFile ~/.ssh/id_ed25519  # 私钥路径

# 配置后只需输入:
ssh bioserver                       # 代替 ssh pweaz@192.168.1.100
scp file.txt bioserver:/data/       # 代替 scp file.txt pweaz@192.168.1.100:/data/

六、Shell 脚本进阶

6.1 错误处理(脚本必备开头)

#!/bin/bash
set -euo pipefail
# set -e          命令出错立即退出(不会默默继续执行后面的命令)
# set -u          使用未定义变量时报错(防止拼写错误导致空变量)
# set -o pipefail 管道中任一命令失败则整个管道失败(默认只看最后一个命令的状态)

6.2 变量和参数解析

#!/bin/bash
set -euo pipefail

# 位置参数
# $0  脚本名
# $1  第一个参数
# $#  参数个数
# $@  所有参数

# 带默认值的变量
THREADS=${1:-4}                    # 如果没传第1个参数,默认为 4
OUTPUT=${2:-"results"}             # 如果没传第2个参数,默认为 results

# 更规范的参数解析(用 getopts 或 while 循环)
INPUT=""
THREADS=4
OUTPUT="results"

while [[ $# -gt 0 ]]; do          # 当还有参数时循环
    case "$1" in
        -i|--input)                # -i 或 --input 后面跟输入文件
            INPUT="$2"
            shift 2                # 跳过这两个参数
            ;;
        -t|--threads)              # -t 或 --threads 后面跟线程数
            THREADS="$2"
            shift 2
            ;;
        -o|--output)               # -o 或 --output 后面跟输出目录
            OUTPUT="$2"
            shift 2
            ;;
        -h|--help)                 # -h 或 --help 显示帮助
            echo "用法: $0 -i input.fq -t 8 -o outdir"
            exit 0
            ;;
        *)                         # 未知参数
            echo "错误: 未知参数 $1" >&2
            exit 1
            ;;
    esac
done

# 检查必需参数
if [[ -z "$INPUT" ]]; then         # -z 判断字符串是否为空
    echo "错误: 必须指定 -i 输入文件" >&2
    exit 1
fi

6.3 函数

#!/bin/bash
set -euo pipefail

# 定义函数
check_file() {
    local file="$1"                # local 声明局部变量,不污染全局
    if [[ ! -f "$file" ]]; then    # -f 判断文件是否存在
        echo "错误: 文件不存在: $file" >&2
        return 1                   # 返回非零表示失败
    fi
    echo "文件检查通过: $file"
    return 0
}

# 调用函数
check_file "input.fastq" || exit 1

# 带返回值的函数
get_sample_name() {
    local filepath="$1"
    # 从路径中提取样本名:/data/sample01_R1.fastq.gz → sample01
    local filename
    filename=$(basename "$filepath")          # 去掉路径部分
    echo "${filename%%_R[12]*}"               # 去掉 _R1 或 _R2 及之后的部分
}

# 使用函数返回值
SAMPLE=$(get_sample_name "/data/sample01_R1.fastq.gz")
echo "样本名: $SAMPLE"                        # 输出: sample01

6.4 数组和循环

#!/bin/bash
set -euo pipefail

# 定义数组
SAMPLES=("sample01" "sample02" "sample03" "sample04")

# 遍历数组
for sample in "${SAMPLES[@]}"; do             # [@] 展开所有元素
    echo "正在处理: $sample"
    fastp -i "${sample}_R1.fq.gz" \
          -I "${sample}_R2.fq.gz" \
          -o "clean_${sample}_R1.fq.gz" \
          -O "clean_${sample}_R2.fq.gz" \
          -j "${sample}_fastp.json" \
          -h "${sample}_fastp.html"
done

# 从文件读取样本列表(每行一个样本名)
while IFS= read -r sample; do                # IFS= 防止去掉前后空格
    echo "处理: $sample"
done < sample_list.txt

# C 风格 for 循环
for ((i=1; i<=10; i++)); do
    echo "第 $i 次迭代"
done

# 条件判断
if [[ -d "$OUTPUT" ]]; then                   # -d 判断目录是否存在
    echo "输出目录已存在"
else
    mkdir -p "$OUTPUT"                         # -p 递归创建目录
    echo "已创建输出目录: $OUTPUT"
fi

七、性能监控

# free:查看内存使用
free -h                            # -h 人类可读格式
# 重点看 available 列:系统实际可用内存(含可回收的缓存)

# iostat:查看磁盘 I/O 状态
iostat -x 2 5                      # 每2秒刷新,共5次
# 需要安装:sudo apt install sysstat
# 重点看 %util 列:接近 100% 说明磁盘是瓶颈

# sar:系统综合监控(CPU/内存/网络/磁盘历史数据)
sar -u 2 5                         # CPU 使用率,每2秒采样,共5次
sar -r 2 5                         # 内存使用率
sar -n DEV 2 5                     # 网络流量

# vmstat:虚拟内存统计
vmstat 2 5                         # 每2秒输出一次,共5次
# 重点:si/so(swap in/out)如果持续非零,说明内存不足

# 实用组合:判断服务器当前负载
uptime                             # 查看平均负载(1/5/15分钟)
# load average 值 > CPU 核数 → 系统过载
nproc                              # 查看 CPU 核数

八、生信场景实战

8.1 批量处理多样本

#!/bin/bash
set -euo pipefail

# 场景:50 个样本的 fastq 需要质控 + 比对
DATADIR="/data/raw"
OUTDIR="/data/results"
REF="/data/ref/hg38"
THREADS=8

mkdir -p "$OUTDIR"

# 自动发现所有样本(从 R1 文件名提取样本名)
for r1 in "${DATADIR}"/*_R1.fastq.gz; do
    sample=$(basename "$r1" _R1.fastq.gz)      # 提取样本名
    r2="${DATADIR}/${sample}_R2.fastq.gz"       # 构造 R2 路径

    # 检查 R2 是否存在
    if [[ ! -f "$r2" ]]; then
        echo "警告: 缺少 R2 文件,跳过 $sample" >&2
        continue                                # 跳过此样本
    fi

    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始处理 $sample"

    # Step 1: 质控
    fastp -i "$r1" -I "$r2" \
          -o "${OUTDIR}/${sample}_clean_R1.fq.gz" \
          -O "${OUTDIR}/${sample}_clean_R2.fq.gz" \
          -j "${OUTDIR}/${sample}_fastp.json" \
          -w "$THREADS"

    # Step 2: 比对
    bowtie2 -x "$REF" \
            -1 "${OUTDIR}/${sample}_clean_R1.fq.gz" \
            -2 "${OUTDIR}/${sample}_clean_R2.fq.gz" \
            -p "$THREADS" \
            2> "${OUTDIR}/${sample}_bowtie2.log" \
    | samtools sort -@ "$THREADS" -o "${OUTDIR}/${sample}.sorted.bam"

    # Step 3: 建索引
    samtools index "${OUTDIR}/${sample}.sorted.bam"

    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $sample 处理完成"
done

8.2 GNU parallel 并行任务

# 安装
sudo apt install parallel

# 基本用法:把串行循环变成并行
# 串行(一个一个跑,慢):
for f in *.fastq.gz; do fastqc "$f" -o qc_results/; done

# 并行(同时跑多个,快):
ls *.fastq.gz | parallel -j 8 fastqc {} -o qc_results/
# -j 8     最多同时跑 8 个任务
# {}       被替换为每一行输入

# 从文件读取样本列表并行处理
cat sample_list.txt | parallel -j 4 --progress \
    "fastp -i {}_R1.fq.gz -I {}_R2.fq.gz \
           -o clean_{}_R1.fq.gz -O clean_{}_R2.fq.gz \
           -j {}_fastp.json"
# --progress  显示进度

# 高级用法:多参数并行
parallel -j 4 --colsep '\t' \
    "bowtie2 -x {1} -1 {2} -2 {3} -S {4}" \
    :::: tasks.tsv
# --colsep '\t'  用 Tab 分隔参数
# {1},{2},{3},{4} 分别对应 tasks.tsv 每行的第1-4列
# tasks.tsv 格式:ref_index \t R1.fq \t R2.fq \t output.sam

# 带重试的并行(某个任务失败自动重试)
cat sample_list.txt | parallel -j 4 --retries 3 \
    "bash process_sample.sh {}"

8.3 日志管理

#!/bin/bash
set -euo pipefail

# 规范的日志函数
LOGFILE="pipeline_$(date '+%Y%m%d_%H%M%S').log"

log() {
    local level="$1"                           # INFO / WARN / ERROR
    shift
    local msg="$*"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $msg" | tee -a "$LOGFILE"
    # tee -a  同时输出到屏幕和追加到日志文件
}

log INFO "流程开始"
log INFO "输入目录: /data/raw"

# 带错误捕获的执行
run_step() {
    local step_name="$1"
    shift
    log INFO "开始: $step_name"
    if "$@" >> "$LOGFILE" 2>&1; then           # 执行命令,输出写入日志
        log INFO "完成: $step_name"
    else
        log ERROR "失败: $step_name (退出码: $?)"
        exit 1
    fi
}

run_step "质控" fastp -i input_R1.fq.gz -I input_R2.fq.gz -o clean_R1.fq.gz -O clean_R2.fq.gz
run_step "比对" bowtie2 -x ref -1 clean_R1.fq.gz -2 clean_R2.fq.gz -S output.sam

log INFO "全部流程完成"

九、常见报错与解决

1. Permission denied

# 报错:bash: ./script.sh: Permission denied
# 原因:脚本没有执行权限
chmod +x script.sh                 # 加上执行权限
# 或者用 bash 直接执行(不需要执行权限):
bash script.sh

2. No space left on device

# 报错:write error: No space left on device
# 原因:磁盘满了
df -h                              # 查看哪个分区满了
du -sh /home/pweaz/* | sort -rh | head  # 找占空间最大的目录
# 清理方法:删除不需要的中间文件(如 SAM 文件,已转成 BAM 就可以删)
find /data -name "*.sam" -size +1G -exec ls -lh {} \;  # 先查看再决定删除

3. Command not found

# 报错:fastp: command not found
# 原因:软件未安装 或 未激活 conda 环境 或 不在 PATH 中
which fastp                        # 查找命令位置
conda activate bioinfo             # 激活正确的 conda 环境
echo $PATH                         # 检查 PATH 环境变量
export PATH="/path/to/software:$PATH"  # 临时添加到 PATH

4. Killed / Out of Memory

# 报错:进程被 Killed,或 OOM killer 杀掉
# 原因:内存不够
free -h                            # 查看内存
dmesg | tail -20                   # 查看内核日志确认是否 OOM
# 解决:减少线程数(每个线程都要内存)、分批处理数据、换大内存节点

5. Broken pipe

# 报错:write error: Broken pipe
# 原因:管道下游命令提前退出(如 head 只要前10行,上游还在输出)
# 通常无害,但如果影响结果:
set +o pipefail                    # 临时关闭 pipefail
samtools view file.bam | head -10
set -o pipefail                    # 恢复

6. Argument list too long

# 报错:/bin/ls: Argument list too long
# 原因:通配符展开的文件太多(如目录下有几十万个文件)
# 解决:用 find + xargs 代替通配符
find /data -name "*.fq.gz" | xargs -I {} cp {} /backup/
# xargs -I {}  把每行输入替换到 {} 的位置
# 或者用 find -exec
find /data -name "*.fq.gz" -exec cp {} /backup/ \;

十、命令速查表

文本处理

命令 用途 常用示例
awk 按列处理文本 awk -F'\t' '{print $1,$3}' file
sed 流式查找替换 sed 's/old/new/g' file
cut 按列截取 cut -f1,3 -d'\t' file
sort 排序 sort -k2,2n -k3,3nr file
uniq 去重 sort file \| uniq -c
wc 统计行/词/字节 wc -l file
tr 字符替换/删除 tr '\t' ',' < file
paste 按列合并文件 paste file1 file2
join 按键合并文件 join -t'\t' -1 1 -2 1 a.tsv b.tsv

进程管理

命令 用途 常用示例
nohup 不挂断运行 nohup cmd > log 2>&1 &
tmux 终端复用 tmux new -s name
screen 终端复用 screen -S name
top/htop 实时进程监控 htop
ps 进程快照 ps aux \| grep name
kill 终止进程 kill -9 PID
jobs 后台任务列表 jobs -l

文件系统

命令 用途 常用示例
df 磁盘使用 df -h
du 目录大小 du -sh *
find 查找文件 find . -name "*.bam"
ln 创建链接 ln -s target link
chmod 修改权限 chmod 755 script.sh
tar 打包压缩 tar -czf archive.tar.gz dir/

网络工具

命令 用途 常用示例
wget 下载文件 wget -c URL
curl 请求/下载 curl -O URL
scp SSH 文件传输 scp file user@host:/path/
rsync 增量同步 rsync -avz src/ dst/
ssh 远程登录 ssh user@host

性能监控

命令 用途 常用示例
free 内存使用 free -h
iostat 磁盘 I/O iostat -x 2 5
sar 综合监控 sar -u 2 5
vmstat 虚拟内存 vmstat 2 5
uptime 系统负载 uptime
nproc CPU 核数 nproc

十一、延伸资源

在线教程

  • Linux 命令大全man command 或在线 https://man7.org/linux/man-pages/ —— 每个命令的官方手册
  • AWK 教程:GNU AWK 用户指南,搜索 "GNU Awk User's Guide"
  • sed & awk (O'Reilly):经典参考书,系统学习文本处理
  • The Linux Command Line:免费电子书,适合从基础到进阶系统学习

生信专项

  • Bioinformatics one-liners:搜索 "bioinformatics one-liners github",收集了常用的 awk/sed 单行命令
  • bioawk:awk 的生信增强版,原生支持 FASTA/FASTQ/BED/GFF 格式
  • GNU Parallel 官方教程parallel --citation 查看引用,man parallel_tutorial 查看教程

练习建议

  1. 拿一个小的 GFF 文件练 awk 提取和统计
  2. 写一个完整的批处理脚本处理 3-5 个样本
  3. 在服务器上用 tmux 跑一个需要几小时的任务
  4. GNU parallel 把串行脚本改成并行版本

学习路径建议:先掌握 awk/sed(面试高频)→ 学会 tmux + nohup(实战必备)→ 写规范的 Shell 脚本(set -euo pipefail + 参数解析 + 日志)→ 用 parallel 加速批量任务。这四步走完,Linux 命令行就从"能用"变成"好用"了。