Enveloppement d'une boucle autour d'une command 'sed' – traitement de nombreux files dans un seul directory

J'ai des files text contenant de nombreuses lignes, dont certaines commencent par ">" (c'est un file * .fasta et le ">" marque le début d'un nouveau conteneur d'information):

>header_name1 sequence_info >header_name2 sequence_info 

Je veux append le nom du file dans lequel ces lignes se trouvent dans l'en-tête. Par exemple, si le file est nommé "1_nc.fasta", toutes les lignes du file commençant par> doivent porter l'label "001":

 >001-header_name1 sequence_info >001-header_name2 sequence_info 

Quelqu'un gentil m'a fourni cette ligne:

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

En conséquence, tous les en-têtes de 2_nc.fasta doivent commencer par "002-", 3_nc.fasta -> "003-", etc.

Je sais comment écrire des scripts de travail parallèles, mais les tâches sont effectuées si rapidement, je pense qu'un script qui traite en série tous les files dans une boucle est beaucoup mieux. Malheureusement, je ne peux pas le faire tout seul.

Ajout de twist: 11_nc.fasta et 149_nc.fasta ne sont pas disponibles.

Comment puis-je boucler cela à travers tous les 500 files de mon directory?

Cela devrait faire l'affaire. Je casse le nom de file au trait de soulignement pour get le préfixe numérique, puis j'utilise un printf pour le mettre à zéro à une string de trois numbers.

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

Cela semble le faire

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

Testez-le comme ci-dessus pour un aperçu, puis retirez l' echo pour voir ce que le contenu sera:

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

Pour créer les nouveaux files, ajoutez la redirection

 for f in * ; do sed "s/^>/>$(printf %03d "${f%%_*}")/" "$f" > "$(printf %03d "${f%%_*}")_tagged.fasta"; done 
 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 

Résumé

  n varies from 0000 -> 000999 M varies from 0 -> 999 ssortingp off the first 3 chars ${n#???} N is computed by removing the last 3 chars from n then what remains is then ssortingpped , 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-/" 

Cela devrait fonctionner pour bash:

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

L'astuce consistait à étendre l'indice à trois numbers. Ensuite, vous avez besoin "au lieu de" pour permettre l'expansion de $ addme