Calcula posições relativas em cadeias

1

Exemplo de arquivo de entrada:

#name   complete(cs)    len(cs) simple(ss)  len(ss) position(ss)
NAME1   A0AAA000AAA00A  14      AAAAAAAA    8        4,6
NAME2   AAAA0AA00000A   13      AAAAAAA     7        7

Digamos que eu esteja interessado em conhecer a posição correspondente na string completa (cs) de algumas letras da string simplificada (ss), dada na coluna position (ss). Nota: na string simples (ss), apenas letras são permitidas. Na string completa, todos os caracteres são permitidos.

Neste exemplo, ele retornaria:

Arquivo de saída de amostra:

#name   complete(cs)    len(cs) simple(ss)  len(ss) pos(ss) pos(cs)
NAME1   A0AAA000AAA00A  14      AAAAAAAA    8        4,6    5,10
NAME2   AAAA0AA00000A   13      AAAAAAA     7        7      13

Atualmente, estou construindo esse arquivo usando python, mas tenho certeza de que existe uma saída fácil para o Unix.

    
por dovah 30.07.2014 / 10:47

2 respostas

1

Uma solução perl :

$ perl -anle '
    print "$_ position(cs)" and next if /^#/;
    printf "%s",$_;
    for $pos_ss (split ",",$F[5]) {
        $char = substr($F[3],$pos_ss-1,1);
        @cs = split //,$F[1];
        @cs_idx = grep {$cs[$_] eq $char} 0..$#cs;
        push @res,++$cs_idx[$pos_ss-1];
    }
    printf "%14s\n", join ",",@res;
    @res=();
' file
#name   complete(cs)    len(cs) simple(ss)  len(ss) position(ss) position(cs)
NAME1   A0AAA000AAA00A  14      AAAAAAAA    8        4,6          5,10
NAME2   AAAA0AA00000A   13      AAAAAAA     7        7            13

Como funciona

  • As primeiras duas linhas imprimem a entrada original.
  • for $pos_ss (split ",",$F[5]) : dividimos o campo 6, obtemos cada índice desejado em string simples.
  • $char = substr($F[3],$pos_ss-1,1) : obtém o caractere no índice fornecido em uma string simples.
  • @cs = split //,$F[1] : obtemos todos os caracteres em sequência completa, salve-os em uma matriz.
  • @cs_idx = grep {$cs[$_] eq $char} 0..$#cs : obtém todos os índices na matriz @cs , cujo valor é igual a $char .
  • push @res,++$cs_idx[$pos_ss-1] : salve o índice que desejamos para o array @res .
  • As duas últimas linhas apenas imprimem o resultado que obtivemos e esvaziam @res array para o próximo uso.
por 30.07.2014 / 11:53
1

Isso pode ser um começo com operadores bash e informações codificadas. É bastante auto-explicativo:

#!/bin/bash

word="A0AAA000AAA00A"
required=(4 6)
match="A"
w=$word

# get the positions of $match in $word
while [ ! -z "$w" ]; do
    n=$(expr index "$w" $match)
    w=${w:$n}
    counter=$(( counter + n ))
#   echo "position $counter. now w=$w"
    pos+=($counter)
done

echo "All positions: ${pos[@]}"

# print the position of $match in $word on positions given by $required
for i in "${required[@]}"
do
    echo "position $i: ${pos[i-1]}"
done

Um caso genérico pode ser feito com algum tipo de while read; do... done < file , buscando as colunas necessárias.

    
por 30.07.2014 / 11:17