extrair determinada string, pesquisar e substituir ou manter uma string mais longa contendo o valor extraído

1

O arquivo de entrada que precisa ser editado é como abaixo (pode ter mais linhas):

bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1   intron_FBgn0035847:4_FBgn0035847:3  61  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
2   intron_FBgn0032515:2_FBgn0032515:4  72  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
3   intron_FBgn0266486:5_FBgn0266486:4  58  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
4   intron_FBgn0031359:10_FBgn0031359:7 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
4   intron_FBgn0031359:10_FBgn0031359:8 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
4   intron_FBgn0031359:10_FBgn0031359:9 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
536 intron_CR31143:1_CR31143:2  40  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00

Para cada ID na segunda coluna intron_XXXXXXXX: X_XXXXXXXX: X , quero extrair a sequência entre intron _ e a primeira : ( entre a string geralmente, mas nem sempre começa com FBgn).

Então eu tenho uma lista como a seguir (uma coluna para FBgn e a outra coluna para o nome correspondente que eu quero que o FBgn seja convertido):

## FlyBase Gene Mapping Table   
## Generated: Fri Dec 20 12:37:29 2013  
## Using datasource: dbi:Pg:dbname=fb_2014_01_reporting;host=flysql9;port=5432...   
FBgn0035847 mthl7
FBgn0032515 loqs
FBgn0266486 CG45085
FBgn0031359 CG18317

Depois, quero pesquisar a string extraída na primeira coluna da lista.

Se a string extraída tiver o valor correspondente na segunda coluna, quero substituir o ID inteiro intron_FBgnXXXXXX: X_FBgnXXXXXX: X pelo nome correspondente na segunda coluna.

Se a string extraída não existir na primeira coluna, eu quero substituir o ID inteiro intron_XXXXXXXX: X_XXXXXXXX: X pela string extraída.

Eu tenho um script como o seguinte:

ref="gene_map_table_fb_2014_01_short.tsv"
target="HC25_LNv_ZT02_intron_results.txt"
output="temptemp.txt"

declare -A map
while read line
do
if [[ ! -z "$line" ]] && [[ ! "$line" =~ ^#.* ]]
then
key=$(echo "$line" | cut -f 1)
value=$(echo "$line" | cut -f 2)
map[$key]=$value
fi
done < $ref

while read line
do
  key=$(echo "$line" | sed -n 's/.*_\([^\.]*\)\:.*//p' | head -1)
if [ ! -z "$key" ]
then
  echo "$line" | sed 's/intron_[^[:space:]]*/'${map[$key]}'/g' >> $output
else
  echo "$line" | sed 's/intron_[^[:space:]]*/'$key'/g' >> $output
fi
done < $target

Tudo parece funcionar bem, exceto que o arquivo de saída não possui as linhas cujo ID não inicia com o FBgn.

    
por Karli 09.10.2014 / 23:04

2 respostas

0

Você pode fazer isso:

cat gene_map_table_fb_2014_01_short.tsv  |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g

Primeiro, cat seu arquivo, Em seguida, exclua a primeira linha (cabeçalho das colunas com d1), imprima toda a coluna, depois, segure 4_FBgn0035847 com awk 'BEGIN{FS=":"} {print $2}' e, em seguida, elimine number_ com sed s/._//g

A saída é:

FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
CR31143

No entanto, se sua linha final for extra e você quiser removê-la, poderá fazê-lo:

cat gene_map_table_fb_2014_01_short.tsv  |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g |sed '$d'

Então, a saída é:

FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
    
por 09.10.2014 / 23:29
0

Usando awk

Isso cria uma saída separada por tabulações:

$ awk -v OFS="\t" 'NR==FNR{a[$1]=$2;next} FNR==1{print;next} {sub(/intron_/, "", $2); sub(/:.*/,"",$2);if ($2 in a) $2=a[$2];print}' gene_map_table_fb_2014_01_short.tsv HC25_LNv_ZT02_intron_results.txt
bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1       mthl7   61      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
2       loqs    72      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
3       CG45085 58      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
536     CR31143 40      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00

Explicação:

  • -v OFS="\t"

    Isso torna o separador de campos de saída em uma guia.

  • NR==FNR{a[$1]=$2;next}

    Isso cria uma matriz associativa, a , com base no primeiro arquivo na linha de comando, com a primeira coluna como chave e a segunda coluna como valor. O comando next instrui awk a pular o restante dos comandos e pular para a próxima linha.

    O arquivo de mapeamento contém algumas linhas de comentário. Poderíamos facilmente ter adicionado uma instrução if extra para evitar que eles fossem adicionados à matriz a . No entanto, uma vez que eles não fazem mal, nós pulamos essa complicação.

  • FNR==1{print;next}

    Isto imprime a linha de cabeçalho inalterada.

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

    Isso remove o fluff do segundo campo deixando apenas a string que queremos.

  • 'if ($ 2 in a) $ 2 = a [$ 2]

    Se a string do segundo campo estiver presente como uma chave na matriz a , então substituímos seu valor correspondente.

  • print

    A linha revisada é impressa.

Usando bash

No script, substitua

if [ ! -z "$key" ]

Com:

if [[ "$key" && "${map[$key]}" ]]

O que o script parece precisar saber neste momento é se key estava presente em map ou não. O teste revisado garante não apenas que key não está vazio, mas que está em map .

Com essa alteração, recebo a saída:

$ cat temptemp.txt 
bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1       mthl7   61      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
2       loqs    72      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
3       CG45085 58      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
536     CR31143 40      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00

Como um aparte em text , [ ! -z "$key" ] retornará verdadeiro se key não estiver vazio. Isso é equivalente a [ -n "$key" ] . Como esse é um teste tão comum, ele pode ser reduzido ainda mais para [ "$key" ] . Isso pode ser usado para simplificar várias linhas no script bash .

    
por 09.10.2014 / 23:24