¿Cómo eliminar cuatro caracteres aleatorios antes de la extensión .de varios archivos usando un bucle for?

¿Cómo eliminar cuatro caracteres aleatorios antes de la extensión .de varios archivos usando un bucle for?

Estoy trabajando en un proyecto de investigación de pregrado que tiene mucho que ver con la bioinformática y estoy siguiendo un proceso de procesamiento de archivos. Algunos antecedentes: estoy trabajando con datos metagenómicos de escopeta que son muestras muy grandes de A, T, G, C (nucleótidos en una muestra de ADN) y, por lo que he recopilado, algunos calificadores. Ya he seguido algunos pasos del proceso que recortaron y limpiaron algunos archivos, además de agregar algunos calificadores. Lo importante es que estas lecturas son en su mayoría lecturas finales emparejadas, es decir, dos archivos que leen los nucleótidos de derecha a izquierda y de izquierda a derecha.

Antes de esto, había llenado mi cabeza básicamente solo con biología y ecología, por lo que realmente no tengo ningún contexto para codificar o cómo/por qué hacer cosas o prácticas/funciones comunes, etc. Entiendes el punto.

Dicho esto, aprendí por mi cuenta bucles for y manipulación de cadenas muy básicos en UNIX, creando algunos archivos bash que se ejecutaban en diferentes carpetas usando diferentes módulos y funciones. Aquí hay un código de ejemplo:

cd ~/ncbi/public/sra/indian

for forward_read_file in *_1.fastq

do
rev=_2
reverse_read_file=${forward_read_file/_1/$rev}
perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i ${forward_read_file} -irev ${reverse_read_file} -c 1 -t5 -t3

rm ${forward_read_file} ${reverse_read_file}
done

#CAMEROON
cd ~/ncbi/public/sra/cameroon

for forward_read_file in *_1.fastq

do
rev=_2
reverse_read_file=${forward_read_file/_1/$rev}
perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i ${forward_read_file} -irev ${reverse_read_file} -c 1 -t5 -t3

rm ${forward_read_file} ${reverse_read_file}
done 

y así sucesivamente para muchas carpetas. Utilicé la manipulación de cadenas para que cada iteración del bucle for llamara a los archivos finales emparejados y luego algunos argumentos y parámetros para el módulo que estoy usando.

El gran problema con el que me encuentro ahora es que no puedo pensar en una manera de emparejar los archivos finales emparejados para mi siguiente paso en el proceso, ya que tienen cuatro caracteres aleatorios justo antes de la extensión y no puedo predecirlos. No contienen datos significativos, por lo que mi plan es eliminarlos de los nombres de archivos y proceder como lo he hecho.

A continuación se muestran ejemplos de los archivos problemáticos; el problema son los cuatro caracteres al final de la cadena. Si me deshago de ellos, puedo manipular las cadenas como de costumbre.

SRR5898908_1_prinseq_good_ZsSX.fastq  SRR5898928_2_prinseq_good_VygO.fastq  SRR5898979_1_prinseq_good_CRzI.fastq  SRR6166642_2_prinseq_good_nqVP.fastq  SRR6166693_2_prinseq_good_y_OD.fastq
SRR5898908_2_prinseq_good_HPTU.fastq  SRR5898929_1_prinseq_good_p2mS.fastq  SRR5898979_2_prinseq_good_vYcE.fastq  SRR6166643_1_prinseq_good_fc8y.fastq  SRR6166694_1_prinseq_good_Ka1C.fastq
SRR5898909_1_prinseq_good_X41r.fastq  SRR5898929_2_prinseq_good_uO8g.fastq  SRR5898980_1_prinseq_good_WuPS.fastq  SRR6166643_2_prinseq_good_QUUK.fastq  SRR6166694_2_prinseq_good_ZlNk.fastq
SRR5898909_2_prinseq_good_GbmA.fastq  SRR5898930_1_prinseq_good_3qyA.fastq  

Donde el SRRxxxxx inicial es la muestra y el1o2son lecturas directas e inversas respectivamente, de ahí mi manipulación de cadenas. El problema son los cuatro caracteres al final de la cadena. Si me deshago de ellos, puedo manipular las cadenas como de costumbre. Mi mentor me recomendó que usara las funciones FIND o CUT de alguna manera, y habló sobre usar el retorno de find como una variable para manipular, pero siento que eso seguiría teniendo el mismo problema.

¿Cómo puedo eliminar estos caracteres de forma segura usando un bucle for? O lo que creas que funcionaría mejor.

¡Gracias!

Respuesta1

Pruebe algo como esto:

for forward_read_file in *_1*.fastq; do
   srr=$(echo "$forward_read_file" | cut -d_ -f1)
   rrf_array=( $(find . -name "${srr}_2_*.fastq") )

   case "${#rrf_array[@]}" in
     0) echo "Warning: No reverse read file found for $forward_read_file" > /dev/stderr ;;

     1) reverse_read_file="${rrf_array[1]}"
        perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3
        ;;

     *) echo "Error: multiple reverse read files found for $forward_read_file" > /dev/stderr ;;
   esac

done

Esto itera sobre todos los _1archivos. Se utiliza cutpara extraer la identificación de muestra de SRR y luego la usa con el findcomando para encontrar los archivos coincidentes _2. findLa salida de se almacena en una matriz porque no sabemos cuántos resultados se pueden devolver.

Maneja tres resultados posibles: ninguna coincidencia (no es bueno), exactamente 1 coincidencia (bueno, eso es lo que queremos) y más de 1 coincidencia (nuevamente, no es bueno).

Si solo hay un resultado, extraiga el archivo coincidente de la matriz y procéselo con su script Perl.

Si hay cero o más de un resultado, imprima un mensaje de advertencia en stderr y continúe con el siguiente _1nombre de archivo. Puede agregar ; exit 1(u otro código para manejar el error) antes de ;;esos casos si así lo desea.

Esto ignora todas las partes de los nombres de archivos excepto la identificación de muestra SRR al principio y el _1o _2que lo identifica como un archivo de emparejamiento directo o inverso.

Por cierto, esto podría haberse hecho con una declaración if; then; elseen lugar de una case, pero pensé que era útil manejar cero y más de un caso de manera diferente. p.ej

if [ "${#rrf_array[@]}" == 1 ]; 
  reverse_read_file="${rrf_array[1]}"
  perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3
else
  echo "Warning: unknown problem with reverse read file for $forward_read_file" > /dev/stderr
fi

Si sólo desea ignorar los archivos "problemáticos", elimine el elsebloque.


Por cierto, para que su secuencia de comandos sea más legible, le sugiero hacer algo como esto cerca de la parte superior de su secuencia de comandos:

AFilter='/home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl'

y después:

perl "$AFilter" -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3

Alternativamente, si los scripts de Perl son ejecutables (es decir, con una #!/usr/bin/perllínea shebang o similar y con el indicador ejecutable configurado con chmod +x), puede simplemente agregar /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/a su $PATH:

PATH="$PATH:/home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming"

y ejecuta el script como:

AmbiguityFiltering.pl -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3

Respuesta2

¿A qué te refieres con cambiar el nombre del título?

Como esto:

cat a2 | sed -e 's|\(.*\)\(good_\)\(.*\)\(.fastq\)|mv \1\2\3\4 \1\2\4|'
mv SRR5898908_1_prinseq_good_ZsSX.fastq SRR5898908_1_prinseq_good_.fastq
mv SRR5898928_2_prinseq_good_VygO.fastq SRR5898928_2_prinseq_good_.fastq

información relacionada