2010-06-24 5 views
6

que tienen líneas de datos que tiene este aspecto:eliminación de partes de cadena 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 

¿Cómo puedo usar sed eliminar partes de cadena después cuarta columna de (_ separado) para cada línea. Finalmente Rendimiento:

sp_A0A342_ATPB_COFAR 
sp_A0A342_ATPB_COFAR 
sp_A0A373_RK16_COFAR 
sp_A0A373_RK16_COFAR 
sp_A0A4W3_SPEA_GEOSL 

Respuesta

19

cut es un mejor ajuste.

cut -d_ -f 1-4 old_file 

Esto significa simplemente utilizar _ como delimitador, y mantener campos 1-4.

Si insiste en sed:

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

Este lado izquierdo coincide exactamente con cuatro repeticiones de un grupo, que consiste en un guión seguido por 0 o más que no son subrayados. Después de eso, debemos estar al final de la línea. Todo esto es reemplazado por nada.

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

Aún así la respuesta corte es probablemente más rápido y en general mejor.

1

Sí, cortar es mucho mejor, y sí que coincida con la parte posterior de cada uno es más fácil.

finalmente conseguí un partido con el principio de cada línea:

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

Match "cualquier número de no '_'", ahorrando lo que estaba compensada entre \ (y \), seguido de '_'. Haga esto 4 veces, luego haga coincidir cualquier cosa por el resto de la línea (para ser ignorado). Sustituir con cada una de las coincidencias separadas por '_'.

2

Aquí hay otra posibilidad:

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

donde -E, como -r en GNU sed, se enciende expresiones regulares extendidas para facilitar la lectura.

El hecho de que puede hacerlo en SED, sin embargo, no se debe significar. Me gusta cortar mucho mejor para esto.

1

AWK le gusta jugar en los campos:

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

o, más en general:

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