mantener solo cierta parte de una cadena en una determinada columna

mantener solo cierta parte de una cadena en una determinada columna

Tengo un archivo como este:

id  target_id                               length  eff_length
1   intron_FBgn0000721:20_FBgn0000721:18    1136    243.944268
1   intron_FBgn0000721:19_FBgn0000721:18    1122    240.237419
2   intron_FBgn0264373:2_FBgn0264373:3      56      0
3   intron_FBgn0027570:4_FBgn0027570:3      54      0

Para la segunda columna target_id, solo quiero mantener la cadena (no siempre FBgnXXXX, a veces otros nombres) entre intron_la primera y la primera :. Entonces, el nuevo archivo de salida tendrá el valor más simple para la columna 2, pero el resto del archivo seguirá siendo el mismo.

Intenté con el comando sed pero no sé cómo eliminar la parte que no necesito.

Respuesta1

Usando sedy column:

$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/' file | column -t
id  target_id    length  eff_length
1   FBgn0000721  1136    243.944268
1   FBgn0000721  1122    240.237419
2   FBgn0264373  56      0

La parte clave de esto es el comando sustituto:

s/ intron_([^:]*):\S*/ \1/

Busca intron_y guarda todo después intron_y antes de los primeros dos puntos en la variable 1. [^[:space:]]*coincide con todo, desde esos dos puntos hasta el final del campo. Todo eso se reemplaza por el texto guardado en variable 1.

Usando awkcon salida separada por tabulaciones:

$ awk -v "OFS=\t" '{$2=$2;sub(/intron_/, "", $2); sub(/:.*/, "", $2); print}' file
id      target_id       length  eff_length
1       FBgn0000721     1136    243.944268
1       FBgn0000721     1122    240.237419
2       FBgn0264373     56      0

Explicación:

  • -v "OFS=\t"

    Esto establece el separador de campo de salida en una pestaña. Esto ayuda a alinear las columnas, posiblemente haciéndolas columninnecesarias.

  • $2=$2

    Al imprimir una línea, awkno cambiará a nuestro separador de campo de salida recién especificado a menos que cambiemos algo en la línea. Asignar el segundo campo al segundo campo es suficiente para garantizar que la salida tendrá pestañas.

  • sub(/intron_/, "", $2)

    Esto se elimina intron_del segundo campo.

  • sub(/:.*/, "", $2)

    Esto elimina todo lo que está después de los primeros dos puntos del segundo campo.

  • print

    Esto imprime nuestra nueva línea.

Usar awkcon formato de columna personalizado

Esto es como lo anterior, pero se utiliza printfpara que podamos personalizar el formato de anchos y alineaciones de las columnas según lo deseemos:

$ awk  '{sub(/intron_/, "", $2); sub(/:.*/, "", $2); printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4}' file
id  target_id      length eff_length
1   FBgn0000721      1136 243.944268
1   FBgn0000721      1122 240.237419
2   FBgn0264373        56   0

Aquí la declaración printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4selecciona anchos de columna y alineaciones en el printfestilo habitual.

Usar sedy convertir de separados por tabulaciones a separados por comas

$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/; s/[[:space:]][[:space:]]*/,/g' file 
id,target_id,length,eff_length
1,FBgn0000721,1136,243.944268
1,FBgn0000721,1122,240.237419
2,FBgn0264373,56,0

Respuesta2

Puedes usar perl:

$ perl -anle '
    BEGIN {$" = "\t"}
    print "@{[@F]}" and next if $. == 1;
    $F[1] = $1 if /_([^:]*):/;
    print "@{[@F]}";
' file
id  target_id   length  eff_length
1   FBgn0000721 1136    243.944268
1   FBgn0000721 1122    240.237419
2   FBgn0264373 56      0
3   FBgn0027570 54      0

Explicación

  • -a: divide automáticamente cada línea en una matriz @F.

  • BEGIN {$" = "\t"}: configuramos el separador de lista en tabulador \t, se usa cuando una matriz o un segmento de matriz se interpola en una cadena entre comillas dobles.

  • print "@{[@F]}" and next if $. == 1: Imprimimos el encabezado, procesamos a la siguiente línea.

  • $F[1] = $1 if /_([^:]*):/: obtenemos el valor entre _y primero :, lo guardamos en el segundo elemento en @F.

  • print "@{[@F]}": simplemente imprima el resultado deseado.

Respuesta3

sed -e 'h;s/.*intron_[^:]*\(:[^[:space:]]*\).*/\1/;s/./ /g;;G;;s/\(.*\)\n\(.*\)intron_\([^:]*\):[^[:space:]]*/\2\3\1/' YourFile

En 1 sed (sin tubería) manteniendo la columna. Utiliza el buffer de retención

Versión Posix (así --posixque GNU sed)

información relacionada