Processamento do índice de strings

0

Meu arquivo de entrada se parece com:

#key    string              pos(string)     
key1    AA000AA000000AAA0A  2, 3, 18, 12    
key2    00A00AAA000AAAA00A  3, 18           

Eu gostaria de adicionar uma nova coluna no final de cada linha de chave (separada por tabulação). Se um A for encontrado na coluna 2 do arquivo de entrada, a nova coluna conterá as posições fornecidas na coluna 3 do arquivo de entrada. Se um 0 for encontrado na coluna 2 do arquivo de entrada, a posição não deverá ser impressa na nova coluna.

Basicamente, esta é a saída desejada:

#key    string              pos(string)     Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12    2, 18
key2    00A00AAA000AAAA00A  3, 18           3, 18

Uma breve explicação:
(key1)

    A string
  • no índice 2 tem um A - > item 2 adicionado à nova coluna
  • string no índice 3 tem 0 - > item 3 não adicionado à nova coluna
  • string no índice 12 tem 0 - > item 12 não adicionado à nova coluna
  • A string
  • no índice 18 tem um A - > item 18 adicionado à nova coluna

Estou fazendo isso em python, mas fico presa em um múltiplo para mais de teclas e itens (as sequências são muito longas para processar), então pensei em pedir seus conselhos para uma solução de linha de comando (mais leve) .

O que eu estava pensando é:

  • divida o campo pos (string), obtenha o índice que eu pesquiso no campo de string
  • obtenha o caractere no índice fornecido na string
  • para declaração (?)
por dovah 01.08.2014 / 20:37

3 respostas

1

Como sobre o seguinte script awk :

#!/usr/bin/awk -f
BEGIN {
        FS="\t"
        print "#key\tstring\tpos(string)\tApos(string)"
}

{
        out=""
        printf "%s\t",$0
        split($2,str,"")
        gsub(/ /,"",$3)
        split($3,pos,",")
        for (i in pos){
                if (str[pos[i]]=="A"){
                        out = out pos[i] ", "
                }
        }
        gsub(/, $/,"",out)
        print out
}

Salve-o como (por exemplo) findA.awk e torne-o executável com chmod +x findA.awk .

Em seguida, execute-o em seus dados de entrada e redirecione a saída para um novo arquivo:

./findA.awk input.txt > output.txt
cat output.txt
#key    string  pos(string) Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12    2, 18
key2    00A00AAA000AAAA00A  3, 18   3, 18

A saída não é tão organizada quanto o seu exemplo, pois é delimitada por tabulação (conforme sua solicitação) e a largura da tabulação não se alinha com a largura das várias strings.

    
por 02.08.2014 / 09:45
1

Não sei como você está fazendo agora (seria útil ver seu código Python), mas você pode criar uma lista dos elementos da coluna 3 que apontam para um 'A' na coluna 2 como então:

[i for i in COLUMN3 if COLUMN2[i]=='A']

Isso parece um problema simples, mas talvez eu não entenda completamente. Talvez você esteja esquecendo que as strings são iteráveis?

    
por 01.08.2014 / 21:02
1

Um perl horrível:

$ perl -anle '
    printf "%s    Apos(string)\n",$_ and next if /^#/;
    printf "%s",$_;
    $len = 12 - length((split(/\s+/,$_,3))[-1]);
    for $pos_ss (@F[2..$#F]) {
        $char = substr($F[1],int($pos_ss)-1,1);
        push @res, int($pos_ss) if $char eq 'A';
    }
    printf "%@{[12-4+$len]}s\n", join ", ",@res;
    @res=();
' file
#key    string              pos(string)    Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12   2, 18
key2    00A00AAA000AAAA00A  3, 18          3, 18

Funciona de forma semelhante com a minha solução para esta resposta , além de adicionar a variável $len para calcular o formato, é necessário imprimir a última coluna alinhada.

    
por 02.08.2014 / 14:26