#!/bin/bash
ref="genome.fa"
reads="sample_R1.fastq"
# Validación completa de archivos
if [[ ! -f "$ref" ]]; then
echo "ERROR: Referencia $ref no encontrada" >&2
exit 1
elif [[ ! -s "$ref" ]]; then
echo "ERROR: Referencia $ref está vacía" >&2
exit 1
elif [[ ! -r "$ref" ]]; then
echo "ERROR: Sin permisos de lectura en $ref" >&2
exit 1
else
echo "✓ Usando referencia válida: $ref"
fi
# Verificar calidad de reads
if [[ -f "$reads" ]]; then
read_count=$(wc -l < "$reads")
if (( read_count < 1000 )); then
echo "⚠️ Pocas lecturas detectadas: $((read_count/4)) reads"
else
echo "✓ Archivo de reads válido: $((read_count/4)) reads"
fi
fi
11 Control de Flujo
Este módulo cubre las estructuras de decisión y bucles para automatizar tareas bioinformáticas complejas.
11.1 Estructuras de Decisión
11.1.1 if...then...elif...else
Validación robusta de archivos de entrada:
11.1.2 Operadores de Comparación
# Comparaciones numéricas
coverage=25
if (( coverage >= 30 )); then
echo "Cobertura alta: ${coverage}x"
elif (( coverage >= 10 )); then
echo "Cobertura media: ${coverage}x"
else
echo "Cobertura baja: ${coverage}x - considerar re-secuenciación"
fi
# Comparaciones de strings
formato="fastq"
if [[ "$formato" == "fastq" || "$formato" == "fq" ]]; then
echo "Formato de secuenciación detectado"
fi
11.2 Estructura case
Procesamiento por tipo de archivo biológico:
#!/bin/bash
procesar_archivo() {
local archivo="$1"
local extension="${archivo##*.}"
case "$extension" in
fasta|fa|fas)
echo "🧬 Procesando secuencia FASTA: $archivo"
# Contar secuencias
grep -c "^>" "$archivo" && echo "secuencias encontradas"
;;
fastq|fq)
echo "📊 Procesando reads FASTQ: $archivo"
# QC rápido
total_reads=$(($(wc -l < "$archivo") / 4))
echo "Total de reads: $total_reads"
;;
bam)
echo "🗂️ Procesando alineamiento BAM: $archivo"
samtools flagstat "$archivo" 2>/dev/null || echo "Archivo BAM corrupto"
;;
vcf|vcf.gz)
echo "🔬 Procesando variantes VCF: $archivo"
if [[ "$archivo" == *.gz ]]; then
zcat "$archivo" | grep -v "^#" | wc -l
else
grep -v "^#" "$archivo" | wc -l
fi
echo "variantes encontradas"
;;
bed)
echo "📍 Procesando regiones BED: $archivo"
wc -l < "$archivo" && echo "regiones definidas"
;;
*)
echo "⚠️ Tipo de archivo desconocido: $archivo"
echo "Extensiones soportadas: fasta, fastq, bam, vcf, bed"
return 1
;;
esac
}
# Uso
for archivo in data/*; do
[[ -f "$archivo" ]] && procesar_archivo "$archivo"
done
11.3 Bucles
11.3.1 Bucle for
- Procesamiento por lotes
#!/bin/bash
# Pipeline de QC para múltiples muestras
samples=(SRR001 SRR002 SRR003 SRR004)
reference="hg38.fa"
echo "🚀 Iniciando pipeline de QC y alineamiento"
for sample in "${samples[@]}"; do
echo "
=== Procesando muestra: $sample ==="
# 1. Control de calidad
if [[ -f "raw_data/${sample}_R1.fastq.gz" ]]; then
echo "📊 Ejecutando FastQC..."
fastqc "raw_data/${sample}_R1.fastq.gz" "raw_data/${sample}_R2.fastq.gz" \
-o "qc_reports/" --quiet
fi
# 2. Alineamiento
echo "🎯 Alineando contra referencia..."
bwa mem -t 4 "$reference" \
"raw_data/${sample}_R1.fastq.gz" \
"raw_data/${sample}_R2.fastq.gz" | \
samtools sort -@ 4 -o "alignments/${sample}.sorted.bam"
# 3. Indexado
echo "📇 Indexando BAM..."
samtools index "alignments/${sample}.sorted.bam"
echo "✅ $sample completado"
done
echo "🎉 Pipeline finalizado para ${#samples[@]} muestras"
11.3.2 Bucle while
- Lectura de archivos
#!/bin/bash
# Procesar lista de muestras desde archivo
sample_list="samples.txt"
echo "📋 Procesando muestras desde: $sample_list"
while IFS=$'\t' read -r sample_id condition replicate; do
# Saltar líneas de comentario
[[ "$sample_id" =~ ^#.*$ ]] && continue
echo "Procesando: $sample_id (Condición: $condition, Rep: $replicate)"
# Crear directorio específico
mkdir -p "results/${condition}/${sample_id}"
# Simular análisis
echo "Análisis de expresión diferencial para $sample_id" > \
"results/${condition}/${sample_id}/analysis.log"
done < "$sample_list"
# Ejemplo de samples.txt:
# sample_id condition replicate
# CTRL_01 control 1
# CTRL_02 control 2
# TREAT_01 treatment 1
# TREAT_02 treatment 2
11.3.3 Bucle until
- Monitoreo de procesos
#!/bin/bash
# Monitorear finalización de trabajo en cluster
job_name="blast_search"
echo "⏳ Esperando finalización de trabajo: $job_name"
until ! pgrep -f "$job_name" > /dev/null; do
# Mostrar progreso cada 30 segundos
echo "$(date '+%H:%M:%S') - $job_name aún ejecutándose..."
# Verificar uso de memoria
memory_usage=$(ps -eo pid,comm,pmem | grep "$job_name" | awk '{sum+=$3} END {print sum}')
if [[ -n "$memory_usage" ]] && (( $(echo "$memory_usage > 80" | bc -l) )); then
echo "⚠️ Alto uso de memoria: ${memory_usage}%"
fi
sleep 30
done
echo "✅ Trabajo $job_name finalizado en $(date)"
11.4 Control de Bucles
11.4.1 break
y continue
#!/bin/bash
# Procesamiento con manejo de errores
fastq_files=(*.fastq)
for file in "${fastq_files[@]}"; do
echo "Verificando: $file"
# Saltar archivos vacíos
if [[ ! -s "$file" ]]; then
echo "⚠️ Archivo vacío, saltando: $file"
continue
fi
# Verificar formato FASTQ básico
if ! head -n 4 "$file" | grep -q "^@"; then
echo "❌ Formato FASTQ inválido: $file"
continue
fi
# Verificar si ya fue procesado
if [[ -f "${file%.fastq}.processed" ]]; then
echo "✅ Ya procesado: $file"
continue
fi
# Simular error crítico
if [[ "$file" == *"corrupted"* ]]; then
echo "💥 Error crítico en $file - deteniendo pipeline"
break
fi
# Procesar archivo
echo "🔄 Procesando: $file"
# Aquí iría el procesamiento real
touch "${file%.fastq}.processed"
done
11.5 Ejemplo Bioinformático Integrado
Pipeline completo de análisis de variantes:
#!/bin/bash
set -euo pipefail
# Configuración
reference="data/reference/hg38.fa"
samples_dir="data/samples"
results_dir="results"
min_coverage=10
# Crear estructura de directorios
mkdir -p "$results_dir"/{qc,alignments,variants,reports}
echo "🧬 Pipeline de Análisis de Variantes Iniciado"
echo "=================================="
# Validar archivos de entrada
if [[ ! -f "$reference" ]]; then
echo "❌ Archivo de referencia no encontrado: $reference"
exit 1
fi
# Procesar cada muestra
for sample_dir in "$samples_dir"/*/; do
sample_name=$(basename "$sample_dir")
echo "
📊 Procesando muestra: $sample_name"
# Buscar archivos FASTQ
r1_file=$(find "$sample_dir" -name "*R1*.fastq*" | head -1)
r2_file=$(find "$sample_dir" -name "*R2*.fastq*" | head -1)
if [[ -z "$r1_file" || -z "$r2_file" ]]; then
echo "⚠️ Archivos FASTQ incompletos para $sample_name, saltando..."
continue
fi
# QC y alineamiento
case "${r1_file##*.}" in
gz)
echo "🗜️ Archivos comprimidos detectados"
reads_count=$(($(zcat "$r1_file" | wc -l) / 4))
;;
fastq)
reads_count=$(($(wc -l < "$r1_file") / 4))
;;
*)
echo "❌ Formato no soportado: $r1_file"
continue
;;
esac
echo "📈 Reads encontrados: $reads_count"
# Solo procesar si hay suficientes reads
if (( reads_count < 10000 )); then
echo "⚠️ Muy pocos reads ($reads_count), saltando $sample_name"
continue
fi
# Alineamiento y llamada de variantes (simulado)
bam_file="$results_dir/alignments/${sample_name}.bam"
vcf_file="$results_dir/variants/${sample_name}.vcf"
echo "🎯 Generando alineamiento..."
echo "Simulated BAM for $sample_name" > "$bam_file"
echo "🔬 Llamando variantes..."
echo "Simulated VCF for $sample_name" > "$vcf_file"
echo "✅ $sample_name procesado exitosamente"
done
echo "
🎉 Pipeline completado. Resultados en: $results_dir"
11.6 Buenas Prácticas
11.6.1 Validación y Manejo de Errores
#!/bin/bash
# Función para validar herramientas
check_dependencies() {
local tools=("samtools" "bwa" "fastqc")
local missing=()
for tool in "${tools[@]}"; do
if ! command -v "$tool" &> /dev/null; then
missing+=("$tool")
fi
done
if (( ${#missing[@]} > 0 )); then
echo "❌ Herramientas faltantes: ${missing[*]}"
echo "Instala con: conda install ${missing[*]}"
exit 1
fi
echo "✅ Todas las dependencias disponibles"
}
# Función para progreso visual
show_progress() {
local current=$1
local total=$2
local percent=$((current * 100 / total))
local bar_length=20
local filled=$((percent * bar_length / 100))
printf "\rProgreso: ["
printf "%*s" $filled | tr ' ' '█'
printf "%*s" $((bar_length - filled)) | tr ' ' '░'
printf "] %d%% (%d/%d)" $percent $current $total
}
# Uso en bucle
samples=(sample1 sample2 sample3 sample4 sample5)
total=${#samples[@]}
for i in "${!samples[@]}"; do
show_progress $((i + 1)) $total
# Simular procesamiento
sleep 1
done
echo -e "\n✅ Procesamiento completo"
11.7 Resumen de Comandos
Estructura | Sintaxis | Uso Principal |
---|---|---|
if |
if [[ condition ]]; then ... fi |
Decisiones condicionales |
case |
case $var in pattern) ... ;; esac |
Múltiples opciones |
for |
for item in list; do ... done |
Iteración sobre elementos |
while |
while condition; do ... done |
Bucle con condición previa |
until |
until condition; do ... done |
Bucle hasta condición |
break |
break |
Salir de bucle |
continue |
continue |
Siguiente iteración |
Operadores útiles: - (( ))
para comparaciones numéricas - [[ ]]
para comparaciones de strings y archivos - &&
y ||
para lógica booleana