2010-06-24 23 views
6

mi hanno linee di dati che assomiglia a questo:rimozione di parti di stringa con 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 

Come posso usare sed per eliminare parti di stringa dopo 4a colonna (_ separati) per ogni linea. Infine cedevole:

sp_A0A342_ATPB_COFAR 
sp_A0A342_ATPB_COFAR 
sp_A0A373_RK16_COFAR 
sp_A0A373_RK16_COFAR 
sp_A0A4W3_SPEA_GEOSL 

risposta

19

cut è una migliore vestibilità.

cut -d_ -f 1-4 old_file 

Ciò significa semplicemente utilizzare _ come delimitatore e mantenere i campi 1-4.

Se ti ostini a sed:

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

Questa sinistra corrisponde esattamente quattro ripetizioni di un gruppo, composto da un trattino seguito da 0 o più non sottolineatura. Dopo ciò, dobbiamo essere alla fine della linea. Questo è tutto sostituito da niente.

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

Ancora la risposta di taglio è probabilmente più veloce e generalmente generalmente migliore.

1

Sì, il taglio è decisamente migliore, e sì è più facile abbinare il retro di ciascuno.

Finalmente ho avuto un incontro con l'all'inizio di ogni riga:

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

Match "qualsiasi numero di non '_'", salvando ciò che è stato abbinato tra \ (e \), seguito da '_'. Fatelo 4 volte, quindi abbinate qualcosa per il resto della linea (da ignorare). Sostituire con ciascuna delle partite separate da '_'.

2

Ecco un'altra possibilità:

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

dove -E, come -r in GNU sed, si accende espressioni regolari estese per la leggibilità.

Solo perché si può farlo in sed, però, non significa che si dovrebbe . Mi piace molto tagliare molto meglio per questo.

1

AWK piace giocare nei campi:

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

o, più in generale:

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