Como remover quatro caracteres aleatórios antes da extensão .de vários arquivos usando um loop for?

Como remover quatro caracteres aleatórios antes da extensão .de vários arquivos usando um loop for?

Estou trabalhando em um projeto de pesquisa de graduação que envolve bioinformática e estou percorrendo um pipeline de processamento de arquivos. Algumas informações básicas: estou trabalhando com dados metagenômicos shotgun, que são amostras muito grandes de A, T, G, C (nucleotídeos em uma amostra de DNA) e, pelo que reuni, alguns qualificadores. Já passei por algumas etapas do pipeline que cortaram e limparam alguns arquivos, além de adicionar alguns qualificadores. O importante é que essas leituras sejam, em sua maioria, leituras finais emparelhadas, ou seja, dois arquivos lendo os nucleotídeos da direita para a esquerda e da esquerda para a direita.

Antes disso, eu tinha abarrotado minha cabeça basicamente apenas com biologia e ecologia, então não tenho nenhum contexto para codificação ou como/por que fazer as coisas ou práticas/funções comuns, etc.

Dito isso, aprendi muito básico sobre loops e manipulação de strings no UNIX, criando alguns arquivos bash que percorriam diferentes pastas usando diferentes módulos e funções. Aqui está um exemplo de código:

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 

e assim por diante para muitas pastas. Usei a manipulação de strings para fazer com que cada iteração do loop for chamasse os arquivos finais emparelhados e, em seguida, alguns argumentos e parâmetros para o módulo que estou usando.

O grande problema que estou enfrentando agora é que não consigo pensar em uma maneira de emparelhar os arquivos finais emparelhados para minha próxima etapa no pipeline, pois eles têm quatro caracteres aleatórios logo antes da extensão e não posso prevê-los. Eles não contêm dados significativos, então meu plano é excluí-los dos nomes dos arquivos e proceder como fiz.

Aqui estão alguns exemplos de arquivos com problemas; o problema são os quatro caracteres no final da string. Se eu me livrar deles, posso fazer a manipulação das strings normalmente.

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  

Onde o início SRRxxxxxx é a amostra, e o1ou2são leituras diretas e reversas, respectivamente, daí minha manipulação de strings. O problema são os quatro caracteres no final da string. Se eu me livrar deles, posso fazer a manipulação das strings normalmente. Meu mentor recomendou que eu usasse as funções FIND ou CUT de alguma forma e falou sobre usar o retorno de find como uma variável para manipular, mas sinto que isso ainda causaria o mesmo problema.

Como posso remover esses caracteres com segurança usando um loop for? Ou o que você acha que funcionaria melhor.

Obrigado!

Responder1

Tente algo assim:

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

Isso itera sobre todos os _1arquivos. Ele é usado cutpara extrair o ID da amostra SRR e, em seguida, usa-o com o comando para localizar quaisquer arquivos findcorrespondentes . A saída de é armazenada em um array porque não sabemos quantos resultados podem ser retornados._2find

Ele lida com três resultados possíveis - nenhuma correspondência (não é bom), exatamente 1 correspondência (bom, é isso que queremos) e mais de 1 correspondência (novamente, não é bom).

Se houver apenas um resultado, extraia o arquivo correspondente da matriz e processe-o com seu script Perl.

Se houver zero ou mais de um resultado, imprima uma mensagem de aviso em stderr e continue para o próximo _1nome de arquivo. Você pode adicionar ; exit 1(ou outro código para lidar com o erro) antes de ;;para esses casos, se desejar.

Isso ignora todas as partes dos nomes de arquivos, exceto o ID de amostra SRR no início e o _1ou _2que o identifica como um arquivo de emparelhamento direto ou reverso.

Aliás, isso poderia ter sido feito com uma declaração if; then; elseem vez de uma case, mas achei útil lidar com zero e mais de um caso de maneira diferente. por exemplo

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

Se você quiser apenas ignorar os arquivos "problemáticos", exclua o elsebloco.


Aliás, para tornar seu script mais legível, sugiro fazer algo assim próximo ao topo do seu script:

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

e depois:

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

Alternativamente, se os scripts perl forem executáveis ​​(ou seja, com uma #!/usr/bin/perllinha shebang ou semelhante e com o sinalizador executável definido com chmod +x), você pode simplesmente adicionar /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/ao seu $PATH:

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

e execute o script como:

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

Responder2

Renomear do título é o que você quer dizer?

Assim:

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

informação relacionada