Separando nomes separados por “| personagem ”para pares individuais

1

Eu quero separar os nomes na mesma linha em pares individuais separados.

TMPRSS2|pp9284 AADAT Sample1
ERG    TMPRSS2|pp9284 Sample2
TMPRSS2|pp9284 ETV1 Sample3
PDE4A   MIA|MIA-RAB4B|RAB4B|RAB4B-EGLN2|EGLN2 Sample4

Isso deve ser

TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG    TMPRSS2 Sample2
ERG  pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4

Os vários nomes estão em ambas as colunas, então eu quero pares individuais. Eu tentei o mysql para isso, pois depois de ter pares individuais, quero compará-lo com outra tabela. O strsplit em R só funciona bem quando os vários nomes estão em um número fixo, mas eles variam em cada linha. Posso fazer isso usando sed, awk?

Além disso, há certas colunas, cujos valores permanecem iguais e basicamente permanecem iguais para os valores que estavam na mesma linha. Como devo imprimi-los? Adicionei a terceira coluna, cujos valores são replicados em novas linhas. usei print $ 3 dentro do loop for para imprimi-los também, mas não funciona.

    
por Ron 27.02.2015 / 20:31

3 respostas

4
$ awk '{split($1,a,"|"); split($2,b,"|"); for (i in a) {for (j in b) print a[i],b[j];}}' file
TMPRSS2 AADAT
pp9284 AADAT
ERG TMPRSS2
ERG pp9284
TMPRSS2 ETV1
pp9284 ETV1
PDE4A RAB4B-EGLN2
PDE4A EGLN2
PDE4A MIA
PDE4A MIA-RAB4B
PDE4A RAB4B

Para imprimir também o terceiro campo ( SampleN ), você pode simplesmente adicionar $3 ao comando print dentro dos loops, ou seja,

$ awk '{split($1,a,"|"); split($2,b,"|"); for (i in a) {for (j in b) print a[i],b[j],$3;}}' file
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
    
por 27.02.2015 / 21:07
4

Com bash:

# important to use parentheses, not braces, to localize changes to IFS
# the variable is purposefully unquoted
split_pipe() ( IFS='|'; echo $1 )

while read -r first second third; do
  for word1 in $(split_pipe "$first"); do
    for word2 in $(split_pipe "$second"); do
      echo $word1 $word2 $third
    done
  done
done < file
    
por 27.02.2015 / 21:34
1

Com o% GNUsed, você pode fazer:

sed -E 's/(\|[^ |]+) /| /
        s/(([^|]* )?([^|]*))\|(([^ ]*)(.*))/\n/
        /\n/P;D' <infile

... que imprime ...

TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG    TMPRSS2 Sample2
ERG    pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A   MIA Sample4
PDE4A   MIA-RAB4B Sample4
PDE4A   RAB4B Sample4
PDE4A   RAB4B-EGLN2 Sample4
PDE4A   EGLN2 Sample4

Funciona dividindo e imprimindo e excluindo em partes o conteúdo de uma linha em caracteres extra de \n ewline. O P command P rints vai até o primeiro \n ewline no espaço padrão, então você pode facilmente imprimir apenas uma parte do seu buffer de edição como quiser.

Neste caso, para cada seção dividida por pipe que não contém espaços sed coloca todos os bits em qualquer extremidade do buffer de edição em duas vezes. sed insere as extremidades mais à esquerda e mais à direita à esquerda e à direita da seção dividida por pipe mais à esquerda e segue essa sequência com uma \n ewline, em seguida, coloca as mesmas seleções em qualquer extremidade de todas as divisões pipe seções que permanecem no lado direito do seu \n ewline inserido. Portanto, sed can P rint apenas o bit à esquerda se houver um \n ewline no padrão de espaço, então D elete apenas até o primeiro \n ewline em espaço padrão e tente novamente.

A primeira substituição só acontece uma vez - ela apenas anexa um pipe ao final das seções divididas por pipe, de modo que sempre haverá um pipe para separar - até mesmo para a última ocorrência. O restante do tempo, sed faz o um s/// ubstitution, P reimula a primeira linha no padrão de espaço, então D elimina o mesmo. Quando não puder mais fazer isso, D elimina todo o espaço padrão e puxa a próxima linha de entrada automaticamente.

Um POSIX BRE para fazer a mesma coisa pode ser escrito:

sed '   s/\(|[^ |]\{1,\}\) /| /
        s/^\(\( *[^ |]*  *\)*\([^ |]*\)\)|\(\([^ ]*\)\(.*\)\)/\
/;   /\n/P;D' <infile
    
por 28.02.2015 / 00:15

Tags