
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 _1
arquivos. Ele é usado cut
para extrair o ID da amostra SRR e, em seguida, usa-o com o comando para localizar quaisquer arquivos find
correspondentes . A saída de é armazenada em um array porque não sabemos quantos resultados podem ser retornados._2
find
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 _1
nome 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 _1
ou _2
que o identifica como um arquivo de emparelhamento direto ou reverso.
Aliás, isso poderia ter sido feito com uma declaração if; then; else
em 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 else
bloco.
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/perl
linha 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