2010-06-24 4 views
6

j'ai lignes de données qui ressemble à ceci:de pièces Retrait de chaîne avec Sed

sp_A0A342_ATPB_COFAR_6_+_contigs_full.fasta 
sp_A0A342_ATPB_COFAR_9_-_contigs_full.fasta 
sp_A0A373_RK16_COFAR_10_-_contigs_full.fasta 
sp_A0A373_RK16_COFAR_8_+_contigs_full.fasta 
sp_A0A4W3_SPEA_GEOSL_15_-_contigs_full.fasta 

Comment puis-je utiliser sed pour supprimer des parties de chaîne après 4 colonne (séparés _) pour chaque ligne. Enfin Cédant:

sp_A0A342_ATPB_COFAR 
sp_A0A342_ATPB_COFAR 
sp_A0A373_RK16_COFAR 
sp_A0A373_RK16_COFAR 
sp_A0A4W3_SPEA_GEOSL 

Répondre

19

cut est un meilleur ajustement. Cela signifie simplement utiliser _ comme délimiteur et conserver les champs 1-4.

Si vous insistez sur sed:

sed 's/\(_[^_]*\)\{4\}$//' 

Ce côté gauche correspond exactement à quatre répétitions d'un groupe, composé d'un trait de soulignement suivi par 0 ou plusieurs non-underscores. Après cela, nous devons être à la fin de la ligne. Tout cela est remplacé par rien.

1
sed -e 's/_[0-9][0-9]*_[+-]_contigs_full.fasta$//g' 

Toujours la réponse coupée est probablement plus rapide et généralement mieux.

1

Oui, la coupe est bien meilleure, et oui, le dos de chacun est plus facile. sauver ce qui a été adapté entre \ (et \),

sed -r 's/(([^_]*_){3}([^_]*)).*/\1/' oldFile > newFile 
2
sed -e 's/\([^_]*\)_\([^_]*\)_\([^_]*\)_\([^_]*\)_.*/\1_\2_\3_\4' infile > outfile 

Match "tout numéro non '_'", suivi de:

J'ai finalement obtenu un match en utilisant le début de chaque ligne '_'. Faites ceci 4 fois, puis faites correspondre n'importe quoi pour le reste de la ligne (à ignorer). Substituer à chacun des matches séparés par '_'.

2

Voici une autre possibilité:

sed -E -e 's|^([^_]+(_[^_]+){3}).*$|\1|' 

où -E, comme -r dans GNU sed, tourne sur des expressions régulières étendues pour une meilleure lisibilité.

Juste parce que vous pouvez le faire dans sed, cependant, ne signifie pas que vous devriez . J'aime bien mieux couper pour ça.

1

AWK aime jouer dans les champs:

awk 'BEGIN{FS=OFS="_"}{print $1,$2,$3,$4}' inputfile 

ou, de façon plus générale:

awk -v count=4 'BEGIN{FS="_"}{for(i=1;i<=count;i++){printf "%s%s",sep,$i;sep=FS};printf "\n"}'