Envolvendo um loop em torno de um comando 'sed'-processando muitos arquivos em um único diretório

3

Eu tenho arquivos de texto contendo muitas linhas, das quais algumas começam com ">" (é um chamado arquivo * .fasta, e o ">" marca o início de um novo contêiner de informações):

>header_name1
sequence_info
>header_name2
sequence_info

Eu quero adicionar o nome do arquivo em que essas linhas estão localizadas no cabeçalho. Por exemplo, se o arquivo tiver o nome "1_nc.fasta", todas as linhas dentro do arquivo serão iniciadas com > deve ter o rótulo "001" adicionado:

>001-header_name1
sequence_info
>001-header_name2
sequence_info

Alguém legal me forneceu esta linha:

sed 's/^>/>001-/g' 1_nc.fasta>001_tagged.fasta 

Assim, todos os cabeçalhos no 2_nc.fasta devem começar com "002-", 3_nc.fasta - > "003-" e assim por diante.

Eu sei escrever scripts de tarefas paralelas, mas os trabalhos são feitos tão rapidamente, acho que um script que serialmente processa todos os arquivos em um loop é muito melhor. Infelizmente, não posso fazer isso sozinho.

Torção adicionada: 11_nc.fasta e 149_nc.fasta não estão disponíveis.

Como posso fazer o loop através de todos os 500 arquivos no meu diretório?

    
por nouse 07.03.2017 / 19:15

4 respostas

5

Isso deve fazer o truque. Eu quebro o nome do arquivo no sublinhado para obter o prefixo numérico e, em seguida, uso um printf para zero-pad-lo para uma seqüência de três dígitos.

for file in *.fasta; do
    prefix="$(printf "%03d" "${file%%_*}")"
    sed  "s/^>/>$prefix-/" "$file" > "${prefix}_tagged.fasta"
done 
    
por 07.03.2017 / 19:29
3

Isso parece ser feito

for f in *.fasta ; do echo sed "s/^>/>$(printf %03d "${f%%_*}")-/" "$f"; done

Teste-o como acima para uma pré-visualização, depois remova echo para ver qual será o conteúdo:

for f in *.fasta ; do sed "s/^>/>$(printf %03d "${f%%_*}"-)/" "$f"; done

Para criar os novos arquivos, adicione redirecionamento

for f in * ; do sed "s/^>/>$(printf %03d "${f%%_*}")/" "$f" > "$(printf %03d "${f%%_*}")_tagged.fasta"; done
    
por 07.03.2017 / 19:41
2
for n in 000{0..999}; do
   M=${n#???} N=${n##${n%???}}
   [ -f "${M}_nc.fasta" ] && sed -e "s/^>/&$N-/" < "${M}_nc.fasta" > "${N}_tagged.fasta"
done

Resumo

 n varies from 0000 -> 000999
 M varies from    0 ->    999 strip off the first 3 chars ${n#???}
 N is computed by removing the last 3 chars from n then what remains
   is then stripped , essentially performing the act of padding to 3 digits.

compute the filenames:
   fasda filename = ${M}_nc.fasta <------ input file to sed
   new filename   = ${N}_tagged.fasta <---- output file from sed

   sed command:   "s/^>/&$N-/" 
    
por 08.03.2017 / 05:04
2

Isso deve funcionar para o bash:

for filename in *.fasta; do
  index="00${filename%_*}"
  addme="${index:((-3)):3}"
  sed "s/^>/>$addme-/g" "$filename" > "$addme"_tagged.fasta
done

O truque era expandir o índice para três dígitos. Então você precisa "em vez de" para permitir a expansão de $ addme

    
por 07.03.2017 / 19:39