O arquivo de entrada que precisa ser editado é o seguinte (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 2ª colunaintron_XXXXXXXX:X_XXXXXXXX:X, quero extrair a string entreintron_e o 1º:(entre a string geralmente, mas nem sempre, começa com FBgn).
Então eu tenho uma lista como segue (uma coluna paraFacebooke a outra coluna para o nome correspondente em que desejo 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
Então quero pesquisar a string extraída na primeira coluna da lista.
Se a string extraída tiver valor correspondente na 2ª coluna, quero substituir o ID inteirointron_FBgnXXXXXX:X_FBgnXXXXXX:Xcom o nome correspondente na 2ª coluna.
Se a string extraída não existir na 1ª coluna, quero substituir o ID inteirointron_XXXXXXXX:X_XXXXXXXX:Xcom a 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/.*_\([^\.]*\)\:.*/\1/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 contém linhas cujo ID não começa com FBgn.
Responder1
Você consegue:
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), depois imprima toda a coluna e separe 4_FBgn0035847
com awk 'BEGIN{FS=":"} {print $2}'
Em seguida, elimine number_
comsed s/._//g
A saída é:
FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
CR31143
Porém se sua linha final for extra e você quiser removê-la, 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 |sed '$d'
Então, a saída é:
FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
Responder2
Usandoawk
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 transforma o separador do campo de saída em uma guia.
NR==FNR{a[$1]=$2;next}
Isso cria uma matriz associativa,
a
baseada no primeiro arquivo na linha de comando, com a primeira coluna como chave e a segunda coluna como valor. Onext
comando instruiawk
a pular o restante dos comandos e pular para a próxima linha.O arquivo de mapeamento contém algumas linhas de comentários. Poderíamos facilmente ter adicionado uma
if
instrução extra para evitar que eles fossem adicionados ao arraya
. No entanto, como não causam danos, evitamos essa complicação.FNR==1{print;next}
Isso imprime a linha do cabeçalho inalterada.
{sub(/intron_/, "", $2); sub(/:.*/,"",$2)
Isso remove a penugem do segundo campo, deixando para trás apenas a string que desejamos.
`se ($2 em a) $2=a[$2]
Se a string do segundo campo estiver presente como uma chave em array
a
, então substituímos seu valor correspondente.print
A linha revisada é impressa.
Usandobash
No script, substitua
if [ ! -z "$key" ]
Com:
if [[ "$key" && "${map[$key]}" ]]
O que o script parece precisar saber neste momento é se key
estava presente map
ou não. O teste revisado garante não apenas que key
não esteja vazio, mas que esteja dentro map
.
Com essa alteração, obtenho 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 text
, [ ! -z "$key" ]
retorna verdadeiro se key
não estiver vazio. Isto é equivalente a [ -n "$key" ]
. Como este é um teste muito comum, ele pode ser ainda mais abreviado para [ "$key" ]
. Isso pode ser usado para simplificar várias linhas do bash
script.