com sed :
sed '/|/{H;d;};G;s/\([A-Z0-9]*\)\(.*\n\)\(|[^[:cntrl:]]*\)//;P;d' FILE2 FILE1
deve fazer o truque. É uma adaptação de esta resposta . A explicação detalhada está lá.
Eu tenho uma lista grande de dados, como
FILE1 (4600 linhas)
Genome Gene Boolean
E15-12 VFG000923 1
E15-13 VFG000924 1
E15-14 VFG000926 1
E15-15 VFG000928 1
E15-16 VFG000930 1
E15-17 VFG000932 1
E15-18 VFG000933 0
E15-19 VFG001448 0
E15-24 VFG013465 1
Eu quero sub a informação em col2 para se parecer com:
FILE2 (180 linhas)
VFG000923|fepA
VFG000924|fepB
VFG000926|fepD
VFG000928|fepG
VFG000930|entF
VFG000932|entE
VFG000933|entB
VFG001448|kpsD
VFG001450|kpsM
VFG044165|entS
Fora
Genome Gene Boolean
E15-12 VFG000923|fepA 1
E15-13 VFG000924|fepB 1
E15-14 VFG000926|fepD 1
E15-15 VFG000928|fepG 1
E15-16 VFG000930|entF 1
E15-17 VFG000932|entE 1
E15-18 VFG000933|entB 0
E15-19 VFG001448|kpsD 0
E15-20 VFG001450|kpsM 1
Usando código por @ val0x00ff (veja os comentários)
Genome Gene Boolean
E15-14 VFG000923|fepA 1
E15-14 VFG000924|fepB 0
E15-14 VFG000926|fepD 1
E15-14 VFG000928|fepG 0
Existe uma maneira de fazer isso com sed ou awk?
com sed :
sed '/|/{H;d;};G;s/\([A-Z0-9]*\)\(.*\n\)\(|[^[:cntrl:]]*\)//;P;d' FILE2 FILE1
deve fazer o truque. É uma adaptação de esta resposta . A explicação detalhada está lá.
Isso deve funcionar:
$ awk 'NR==FNR{k=sub(/\|.*/,$1); a[k]=$1; next} ($2 in a){$2=a[$2]}1' file2 file
Genome Gene Boolean
E15_14 VFG000923|fepA 1
E15_14 VFG000924|fepB 1
E15_14 VFG000926|fepD 0
E15_14 VFG000928|fepG 1
E15_14 VFG000930|entF 0
E15_14 VFG000932|entE 0
E15_14 VFG000933|entB 1
E15_14 VFG001448|kpsD 1
E15_14 VFG001450|kpsM 1
E15_14 VFG044165|entS 0
Ou, um pouco mais fácil de ler:
awk 'NR==FNR{
k=sub(/\|.*/,$1);
a[k]=$1;
next
}
($2 in a){
$2=a[$2]
}1' file2 file
NR==FNR{ } : NR é o número da linha de entrada atual e FNR é o número da linha do arquivo atual. Ao ler mais de um arquivo, os dois serão iguais apenas durante a leitura do primeiro arquivo. k=sub(/\|.*/,$1); : remova a parte depois do | da linha (isto só acontece para o primeiro arquivo por causa do NR==FNR como explicado acima). a[k]=$1; : salve o primeiro campo do primeiro arquivo como um valor na matriz a cuja chave é o nome do gene (o primeiro campo com tudo após o | removido). next : pule para a próxima linha. Isso garante que não executemos o próximo bloco durante a leitura do primeiro arquivo. ($2 in a) : se o segundo campo existir como uma chave na matriz a (isso só será executado para o segundo arquivo). $2=a[$2] : defina o segundo campo para o que foi armazenado em a para $2 . 1 : esta é uma abreviação de awk para "imprimir a linha atual". funciona porque a ação padrão quando algo é avaliado como verdadeiro no awk é imprimir a linha atual. Como 1 é sempre verdadeiro, isso será impresso. perl -lne '
@ARGV and %h=(%h, /(.*)\|/ => $_),next;
!@ARGV and !$a++ and print,next;
print s//$h{$1}/r if exists $h{(/\h\K(\S+)(?=\h)/)[0]};
' FILE2 FILE1
%h que é keyed nos dados antes de | e o valor é toda a linha. !@ARGV and !$a++ que significa @ARGV foi esvaziado e estamos vendo a variável $a pela primeira vez. regex /\h\S+\h/ para ver se essa chave existe no hash %h . Quando isso for verdade, substituiremos esse campo pelo valor correspondente a essa chave. Tags text-processing awk sed