Eu estava trabalhando em um trabalho de array para um pipeline pequeno e precisava de uma maneira de executar um comando específico com base no tamanho do arquivo. Encontrei este post e similares que descrevem como fazer isso. No momento estou usando o seguinte:
find $d/*.fasta -size +100M -exec sh -c '
chromap -i -r $1 -o $1.index
chromap --preset hic -x $1.index -r $1 -1 $d/hi-c/${ID}_1.fq.gz -2 $d/hi-c/${ID}_2.fq.gz --SAM -o /dev/stdout -t 48 | \
samtools view -bS -@ 48 | samtools sort -n -@ 48 | samtools view -h | sed -e "s/\/.//" | samtools view -bS -o ${ID}.bam -@ 48
' sh {} \;
que, além da bioinfo e das ferramentas utilizadas que funcionam, parece executar apenas a primeira linha de comando - chromap -i -r $1 -o $1.index
. Então, por algum motivo, ao entrar no segundo conjunto de instruções, o script retorna o seguinte:
Não é possível encontrar o arquivo de sequência /hi-c/_1.fq.gz
indicando que não tem conhecimento das variáveis de ambiente que usei com sucesso até agora ou não pode calcular mais de duas operações ao mesmo tempo? Não tenho pistas ... tentei também algo mais simples, por exemplo
mkdir $d/scaffolding
find $d/*.fasta -size +100M -exec sh -c '
chromap -i -r $1 -o $1.index && mv $1 $1.index $d/scaffolding
' sh {} \;
mas Bash reclama de: mv: the destination '/scaffolding' is not a directory
.
O que devo fazer para que um (ou ambos) funcione? Estou faltando alguma coisa, por favor, se alguém tiver alguma ideia sobre esse assunto, me avise! Desde já, obrigado.
Abordando vários problemas:
$d
e$ID
osh
iniciadofind
não consiga vê-los-H
, para osfasta
arquivos que são links simbólicos,find
verificaria o tamanho do link simbólico em vez do tamanho do arquivo fasta-prune
, para aqueles que são diretórios,find
desceríamos para eles. Você provavelmente desejaria excluí-los completamente! -type d
ou incluir apenas arquivos regulares com-type f
(o que inclui links simbólicos para arquivos regulares com-H
). Adicionar essas verificações não elimina a necessidade-prune
(ou-maxdepth 0
se estiver usando GNUfind
ou compatível).pipefail
opção para que os pipelines retornem falha se algum dos comandos falhar. Essa agora é umash
opção padrão, mas existem algumassh
implementações comodash
essa que ainda não oferecem suporte a ela, então substituísh
porbash
, embora você possa usar qualquer outrash
implementação que suportepipefail
.s/\/.//
estavam fora das aspas, o que significava que era o mesmo ques//.//
which não é um código válidosed
. Aqui estamos usando aspas duplas para as aspas internas e alternando de/
para:
para o separador para evitar ter que escapar do/
. Observe que issos:/.::
remove a primeira ocorrência/
seguida por qualquer caractere único sem nada. Remover/.
literalmente, isso és:/\.::
removers:/\.::g
todas as ocorrências.-exec sh ... {} ';'
, você está executando umsh
por arquivo e também a falha de qualquer um deles não é relatada. Substituindo por-exec sh ... {} +
endereços ambos.Se você pudesse mudar para o zsh, a maioria desses problemas poderia ser facilmente evitada.
find
recursos integrados do , então você não precisa combinar shell globs (seu*.fasta
) comfind
.pipefail
(ao contrário de algumassh
implementações).Você assume que algumas variáveis do shell em seu
sh -c
script embutido são herdadas pelo ambiente. Estes sãod
eID
. Se o shell não os exportar para o ambiente antes defind
ser chamado, osh -c
script não os verá e substituirá strings vazias em seus lugares.Portanto, antes de ligar
find
, certifique-se de ter... no seu roteiro.
Como alternativa, defina-os para o
find
comando ao chamá-lo, assim:Lembre-se também de colocar aspas duplas em todas as expansões de variáveis em seus scripts: