
Me gustaría imprimir el patrón de residuos de Cys de cada línea que figura en file.tsv. file.tsv tiene dos columnas como ID de secuencia y Secuencia. de la secuencia de la segunda columna, el primer carácter "C" debe imprimirse como C, si el siguiente residuo inmediato no es C, entonces el código debe imprimir C#. # debe ocurrir solo una vez para n número de ocurrencias de varios aminoácidos.
Entonces, cuando en la columna, si "C" va seguida de otro carácter, me gustaría imprimir # después de "C". entonces, si la columna de secuencia tiene el valor DCFRCGHCC, entonces debería imprimirse en la tercera columna C#C#CC.
Entrada de ejemplo:
c32_g1_i1_ 3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
c32_g1_i1_ 6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
El resultado debe ser de tres columnas: ID de secuencia, Secuencia, Patrón Cys.
c32_g1_i1_3,GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS,C#C#C#C#C
c32_g1_i1_6,AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX,C#C#CC#C
Respuesta1
El primer script de una sola línea/completo analiza y convierte el formato de archivo descrito en la pregunta; el segundo script completo analiza y convierte un formato de archivo FASTA.
#1
Una sola línea jugada al golf:
perl -lane 'my $s;my @m=$F[1]=~/C.?/g;foreach(@m){$_ eq"CC"?$s.="C":$s.="C#"}push(@F,$s);print(join(",",@F))' infile
Guión completo ampliado:
#!/usr/bin/perl
use strict;
use warnings;
@ARGV == 1 || die("Usage: <command> <input_file>\n");
open(my $in, $ARGV[0]) || die("Could not open input file \"$ARGV[0]\": $!\n");
while(<$in>) {
my $string;
my @fields = split(" ");
my @matches = $fields[1] =~ /C.?/g;
foreach(@matches) {
$_ eq "CC" ? $string .= "C" : $string .= "C#"
}
push(@fields, $string);
print(join(",", @fields) . "\n")
}
close($in);
exit
Explicación:
- El archivo de entrada se procesa línea por línea;
- Cada línea se divide en dos cadenas, la parte antes del espacio y la parte después del espacio;
- Cada subcadena formada por un carácter "C" seguido opcionalmente de otro carácter (opcionalmente para capturar también un carácter "C" al final de la cadena) en la segunda cadena se evalúa y si el carácter que sigue a la "C" es un " C", "C" se añade al final de una cadena temporal personalizada; de lo contrario, se agrega "C#" al final de la cadena temporal personalizada;
- La primera, la segunda y la cadena temporal personalizada se imprimen, separadas por comas, seguidas de una nueva línea;
Salida de muestra:
% cat infile
c32_g1_i1_3 GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
c32_g1_i1_6 AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
% perl -ne 'my $s;my @f=split(" ");my @m=$f[1]=~/C.?/g;foreach(@m){$_ eq"CC"?$s.="C":$s.="C#"}push(@f,$s);print(join(",",@f)."\n")' infile
c32_g1_i1_3,GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS,C#C#C#C#C#
c32_g1_i1_6,AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX,C#C#CC#C#
#2
Versión completa ampliada:
#!/usr/bin/perl
use strict;
use warnings;
@ARGV == 1 || die("Usage: <command> <input_file>\n");
open(my $in, $ARGV[0]) || die("Could not open input file \"$ARGV[0]\": $!\n");
open(my $tmp, "+>", "tmpfile") || die("Could not create temporary file \"tmpfile\": $!\n");
select($tmp);
while(<$in>) {
if(/^>/) {
s/$/ /
}
if(my $next = <$in>) {
if($next !~ /^>/) {
chomp
}
print;
seek($in, -length($next), 1)
}
else {
print
}
}
close($in);
seek($tmp, 0, 0);
select(STDOUT);
while(<$tmp>) {
my $string;
my @fields = split(/ (?!.* )|\n/);
my @matches = $fields[1] =~ /C.?/g;
foreach(@matches) {
$_ eq "CC" ? $string .= "C" : $string .= "C#"
}
push(@fields, $string);
print(join(",", @fields) . "\n")
}
close($tmp);
unlink("tmpfile");
exit
Explicación:
- El archivo de entrada se procesa línea por línea;
- Si la línea actual comienza con un
>
carácter, se agrega un espacio a la línea; si existe una línea siguiente y no comienza con un>
carácter, el carácter de nueva línea se elimina de la línea actual; la línea actual se imprime en un archivo temporal; - El archivo temporal se procesa línea por línea;
- Cada línea se divide en dos cadenas, la parte anterior al último espacio y la parte posterior al último espacio;
- Cada subcadena formada por un carácter "C" seguido opcionalmente de otro carácter (opcionalmente para capturar también un carácter "C" al final de la cadena) en la segunda cadena se evalúa y si el carácter que sigue a la "C" es un " C", "C" se añade al final de una cadena temporal personalizada; de lo contrario, se agrega "C#" al final de la cadena temporal personalizada;
- La primera, la segunda y la cadena temporal personalizada se imprimen, separadas por comas, seguidas de una nueva línea;
- Se elimina el archivo temporal;
Salida de muestra:
% cat infile
>c32_g1_i1_
3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
>c32_g1_i1_
6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
% perl script.pl infile
>c32_g1_i1_,3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS,C#C#C#C#C#C#C#C#C#C#
>c32_g1_i1_,6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX,C#C#CC#C#C#C#CC#C#
Respuesta2
Aquí tienes una awk
versión que podría funcionar para ti.
awk '{OFS=","; $3=$2; sub(/[^C]+/,"",$3); gsub(/[^C]+/,"#",$3); print}' file
Simplemente duplica el segundo campo, luego elimina cualquier secuencia inicial no vacía de caracteres que no sean C en el duplicado, luego reemplaza cada secuencia restante de caracteres que no son C con #
.