substituição sensível a maiúsculas e minúsculas; mesmos identificadores de destino

4

Eu mesmo me esforcei para fazer uma substituição sensível a maiúsculas e minúsculas em um arquivo de texto. Por favor, encontrar abaixo um segmento do meu arquivo sed que estou executando como sed -f file.sed < input.txt > output.txt

 s/\<code_229633_13\>/R77_08349T0/
 s/\<code_229633_138\>/R77_09738T0/
 s/\<code_230519_10\>/R77_04813T0/
 s/\<code_230519_1\>/R77_13591T0/
 s/\<code_230519_13\>/R77_05463T0/
 up to line 14521....

O código está funcionando bem mas Eu também tenho casos em que tenho 2 ou mais IDs de TARGET (code_010512_23 e code_299097_0) passando o mesmo ID de SUBSTITUIÇÃO (R77_14520T0) e gostaria de ter algo como saída como R77_14520T0.ae R77_14520T0.b (linhas 1 e 2 abaixo)

s/code_010512_23/R77_14520T0/ --> R77_14520T0.a
s/code_299097_0/R77_14520T0/ --> R77_14520T0.b

Além disso, um caso mais complexo, mas semelhante, é quando eu tenho o seguinte arquivo de entrada (arquivo input2.txt) :

  ID=gene09464;Name=code_229633_13;isoforms=1           
  ID=mRNA10661;Parent=gene09464;Name=code_229633_13         
  ID=exon26192;Parent=mRNA10661;Name=code_229633_13;Target=R77_08349T0  1   1093    +
  ID=exon26193;Parent=mRNA10661;Name=code_229633_13;Target=R77_08349T0  1094    1873    +

  ID=gene09491;Name=code_229633_138;isoforms=1          
  ID=mRNA10690;Parent=gene09491;Name=code_229633_138            
  ID=exon26252;Parent=mRNA10690;Name=code_229633_138;Target=R77_09738T0 1   411 +

  ID=gene09513;Name=code_230519_10;isoforms=1           
  ID=mRNA10715;Parent=gene09513;Name=code_230519_10         
  ID=exon26311;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0  1   59  +
  ID=exon26312;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0  60  186 +

  ID=gene09511;Name=code_230519_1;isoforms=1            
  ID=mRNA10713;Parent=gene09511;Name=code_230519_1          
  ID=exon26308;Parent=mRNA10713;Name=code_230519_1;Target=R77_13591T0   1   1075    +
  ID=exon26309;Parent=mRNA10713;Name=code_230519_1;Target=R77_13591T0   1076    1128    +

  ID=gene09514;Name=code_230519_13;isoforms=1           
  ID=mRNA10716;Parent=gene09514;Name=code_230519_13         
  ID=exon26316;Parent=mRNA10716;Name=code_230519_13;Target=R77_05463T0  1   219 +

  ID=gene00865;Name=code_010512_23;isoforms=1           
  ID=mRNA00979;Parent=gene00865;Name=code_010512_23         
  ID=exon02477;Parent=mRNA00979;Name=code_010512_23;Target=R77_14520T0  1   143 +

  ID=gene14561;Name=code_299097_0;isoforms=2            
  ID=mRNA16419;Parent=gene14561;Name=code_299097_0          
  ID=exon39828;Parent=mRNA16419;Name=code_299097_0;Target=R77_14520T0   144 193 +
  ID=mRNA16420;Parent=gene14561;Name=code_299097_0          
  ID=exon39828;Parent=mRNA16420;Name=code_299097_0;Target=R77_15554T0   408 457 +

e eu preciso para aplicar as substituições com o mesmo que o anterior apenas nas linhas que contêm a palavra "isoformas", em outras palavras, nas linhas 1,6,10, 15,20, 24 e 28 e em nenhum outro lugar no texto. O formato deste arquivo de entrada seria exatamente como descrito com linhas em branco entre as linhas de "isoformas".

Minha saída desejada

 ID=gene09464;Name=R77_08349T0;isoforms=1           
 ID=mRNA10661;Parent=gene09464;Name=code_229633_13          
 ID=exon26192;Parent=mRNA10661;Name=code_229633_13;Target=R77_08349T0   1   1093    +
 ID=exon26193;Parent=mRNA10661;Name=code_229633_13;Target=R77_08349T0   1094    1873    +
 ID=exon26194;Parent=mRNA10661;Name=code_229633_13;Target=R77_08349T0   1874    4065    +

 ID=gene09491;Name=R77_09738T0;isoforms=1           
 ID=mRNA10690;Parent=gene09491;Name=code_229633_138         
 ID=exon26252;Parent=mRNA10690;Name=code_229633_138;Target=R77_09738T0  1   411 +

 ID=gene09513;Name=Target=R77_04813T0;isoforms=1            
 ID=mRNA10715;Parent=gene09513;Name=code_230519_10          
 ID=exon26311;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0   1   59  +
 ID=exon26312;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0   60  186 +
 ID=exon26313;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0   187 678 +
 ID=exon26314;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0   679 1399    +
 ID=exon26315;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0   1400    1402    +

 ID=gene09511;Name=R77_13591T0;isoforms=1           
 ID=mRNA10713;Parent=gene09511;Name=code_230519_1           
 ID=exon26308;Parent=mRNA10713;Name=code_230519_1;Target=R77_13591T0    1   1075    +
 ID=exon26309;Parent=mRNA10713;Name=code_230519_1;Target=R77_13591T0    1076    1128    +

 ID=gene09514;Name=R77_05463T0;isoforms=1           
 ID=mRNA10716;Parent=gene09514;Name=code_230519_13          
 ID=exon26316;Parent=mRNA10716;Name=code_230519_13;Target=R77_05463T0   1   219 +

 ID=gene00865;Name=R77_14520T0.a;isoforms=1         
 ID=mRNA00979;Parent=gene00865;Name=code_010512_23          
 ID=exon02477;Parent=mRNA00979;Name=code_010512_23;Target=R77_14520T0   1   143 +

 ID=gene14561;Name=R77_14520T0.b;isoforms=2         
 ID=mRNA16419;Parent=gene14561;Name=code_299097_0           
 ID=exon39828;Parent=mRNA16419;Name=code_299097_0;Target=R77_14520T0    144 193 +
 ID=mRNA16420;Parent=gene14561;Name=code_299097_0           
 ID=exon39828;Parent=mRNA16420;Name=code_299097_0;Target=R77_15554T0    408 457 +
    
por user61677 06.03.2014 / 10:36

2 respostas

4

Você não pode fazer esse tipo de coisa com sed , é apenas um editor de fluxo de texto. Experimente este scriptlet Perl:

#!/usr/bin/env perl 

## Set the record separator to \n\n to
## read multiple lines as a single record
$/="\n\n";
## This array will contain all lines of the file
my @lines=<>;

## The list of suffixes
@suffix=(a..z); 

## For each line of the input file
foreach (@lines) {
    ## If the current line (lines are now the actual multiline records
    ## because we set $/ to consecutive newlines) is one we are interested in.
    if (/isoforms.*?Target=(\S+)/s){
    ## Keep a list of seen targets
    $seen{$1}++;
    }

}
## Now that we have processed the entire file
## go back and print each line.
foreach (@lines) {

    ## If this line is one of the ones we're interested in
    if(/Name=(.+?);.*?isoforms=.*?Target=(\S+)/s){
    $name=$1; $target=$2;
    ## This is needed so we can know whether
    ## how many times we've seen this target so far.
    $newseen{$target}++;
    ## If this target exists more than once in the input file
    if ($seen{$target}>1) {
        ## Use the %newseen hash to choose the right letter.
        ## The -1 is needed because the first element of an
        ## array is 0, not 1.
        s/$name/$target.$suffix[$newseen{$target}-1]/;
    }
    else {
        s/$name/$target/;
    }
    }
    print;
}

Salve o script acima como foo.pl , torne-o executável ( chmod a+x foo.pl ) e execute em seu arquivo de entrada:

./foo.pl input.txt > output.txt
    
por 03.03.2014 / 18:58
0

Esqueça o que eu escrevi antes, pensei que você estivesse movendo arquivos. Acho que entendo melhor agora:

sed -r '/isoforms/{\
    N;N;s/(.*Name=)[^;]*(.*Name=)\S*\
    (.*Name=.*Target=)(\S*)(.*)/\
        /}'

Eu corri e funciona para eu substituir as duas primeiras ocorrências de " Nome = código [0-9 _] * " em qualquer conjunto de três linhas começando com uma contendo " isoformas "com a próxima seqüência não whitespace $ VALUE do par de chaves" Target = $ VALUE ".

Eu usei apenas uma amostra de 20 ou mais linhas; então provavelmente precisa de afinação. Além disso, não tenho certeza se entendi o problema do sufixo ". [A | b] " que você mencionou, embora eu tenha certeza de que não o resolvi ainda. Estou bastante confiante de que, seja o que for, pode ser tratado com um teste de ramo ou dois. Vou tentar explicar o que o código significa:

  • / isoforms / sed primeiro observa o fluxo de qualquer linha que contenha essa string.

  • { Quando encontrado, começa a executar o bloco de código localizado dentro das chaves. }

  • N; N; sed lê imediatamente as próximas duas linhas de entrada em seu espaço de padrão para que ele possa operar em três linhas de uma só vez. Se você usou um comando "l" neste ponto para imprimir o espaço do padrão, você verá algo como:

    linha de isoformas \ n linha de gene \ n linha de segmentação

  • s / search / replace / o comando s instrui o sed a executar uma função de pesquisa e substituição no espaço de padrão atual.

  • (regex) cada par de parentes no campo de pesquisa de expressão regular corresponde a uma referência anterior no campo de substituição. Algumas taquigrafia eu usei:

    • [^;] * a próxima sequência de caracteres mais longa que não inclui um ponto e vírgula.

    • \ S * a próxima sequência de caracteres mais longa que não inclui espaço em branco.

  • \ NUM sed incrementa os backreferences de substituição na ordem em que são definidos no campo de pesquisa. Um breve resumo desta pesquisa específica:

    • \ 1 sed procura a string " Name = " e, encontrando três no espaço padrão e três especificados na expressão regular, corresponde a tudo até e incluindo seu primeiro resultado.

    • DESCARREGADO sed descarta a sequência de caracteres mais longa que pode ser encontrada após \ 1 sem incluir um ponto e vírgula.

    • \ 2 Assim como \ 1 , mas para o segundo resultado " Name = ".

    • DESCARTADO sed descarta a próxima sequência de caracteres até encontrar espaço em branco.

    • \ 3 sed corresponde a " Nome = " e tudo o mais até e incluindo " Target = "

    • \ 4 sed corresponde à próxima sequência de caracteres até encontrar espaço em branco

    • \ 5 sed corresponde ao que resta da linha 3

  • Para juntar tudo, eu acabei de substituir as seções DESCARTADO por \ 4 assim:

    \ 1 \ 4 \ 2 \ 4 \ 3 \ 4 \ 5

ENTRADA:

ID=gene09491;Name=code_229633_138;isoforms=1
ID=mRNA10690;Parent=gene09491;Name=code_229633_138
ID=exon26252;Parent=mRNA10690;Name=code_229633_138;Target=R77_09738T0 1 411 +

ID=gene09513;Name=code_230519_10;isoforms=1
ID=mRNA10715;Parent=gene09513;Name=code_230519_10
ID=exon26311;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0 1 59 + ID=exon26312;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0 60 186 +

OUTPUT:

ID=gene09491;Name=R77_09738T0;isoforms=1
ID=mRNA10690;Parent=gene09491;Name=R77_09738T0
ID=exon26252;Parent=mRNA10690;Name=code_229633_138;Target=R77_09738T0 1 411 +

ID=gene09513;Name=R77_04813T0;isoforms=1
ID=mRNA10715;Parent=gene09513;Name=R77_04813T0
ID=exon26311;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0 1 59 +
ID=exon26312;Parent=mRNA10715;Name=code_230519_10;Target=R77_04813T0 60 186 +

    
por 04.03.2014 / 04:47

Tags