-
if ( $1 $2 in array )
não funciona; você tem que fazerif (($1,$2) in array)
. - Você não pode usar
array[$3]
earray[$4]
desse jeito. Seu array parece comarray[chrY,59363551]=“chrY 59363551 G 8 0 7 0 0 0 1 0 5 0 0 0 0 0 0 0 7 0 0 0” array[chrY,59363552]=“chrY 59363552 G 7 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0” ︙
e quando você dizarray[$3]
earray[$4]
, você está se referindo aarray[G]
earray[2]
, etc. que não existem. - A capacidade de especificar
> "filename"
no códigoawk
é um ótimo recurso quando você deseja gravar em vários arquivos. Não é tão útil quando você tem apenas um arquivo de saída - por que você não apenas redireciona a saída do comandoawk
? - Linhas longas são ruins. Quebre comandos longos em linhas curtas. Reduza a duplicação reutilizando as variáveis.
- Não use uma matriz chamada
array
. Isso é como ter uma variável chamadavariable
, um arquivo chamadofile
, uma pessoa chamadaPerson
etc. Use nomes descritivos.
OK, isso dito,
awk 'FNR==NR {file1data[$1,$2]=$0; next}
{ if (($1,$2) in file1data) {
# Save desired values from file2.
file2arg03=$3
file2arg04=$4
file2arg08=$8
file2arg10=$10
file2arg12=$12
pct_file2=($8+$10+$12)/$4
# Get data from file1.
$0=file1data[$1,$2]
pct_file1=($8+$10+$12)/$4
print $1, $2, $3, $4, $8, $10, $12, pct_file1, \
file2arg03, file2arg04, file2arg08, file2arg10, file2arg12, \
pct_file2, pct_file1-pct_file2
} else printf "(%s,%s) in file2 but not file1.%s", $1, $2, ORS
}' treated.bam.tsv untreated.bam.tsv > awkoutput.bam.tsv
Assim como sua versão, isso salva os dados do arquivo1 em uma matriz
e depois faz todo o trabalho / saída enquanto lê o arquivo2.
Ao receber uma linha do arquivo 2,
salva os campos desejados daquela linha em variáveis nomeadas
(também podemos usar outro array, cinco elementos de comprimento)
e, em seguida, restaura os dados da linha correspondente no arquivo1.
Atribuindo a linha inteira a $0
,
isso causa $1
, $2
, $3
, $4
, etc.
para ser restaurado aos seus valores originais.
Você está realmente tendo problemas para escrever uma linha de cabeçalho na saída? Experimente:
{ if (FNR == 1) {
print "chrom pos ref reads_all mismatches deletions insertions pct_file1 …"
} else if (($1,$2) in file1data ) {
file2arg03=$3
︙
OK, aqui está uma versão mais próxima de sua tentativa, e que lida com a linha de cabeçalho:
awk 'FNR==NR {file1line[$1,$2]=$0; next}
{ if (FNR == 1) {
print "chrom pos ref reads_all mismatches deletions insertions pct_file1 ref reads_all mismatches deletions insertions pct_file2 pct_sub …"
} else if (($1,$2) in file1line ) {
# Get data from file1.
split(file1line[$1,$2], file1arg)
pct_file1=(file1arg[8]+file1arg[10]+file1arg[12])/file1arg[4]
pct_file2=($8+$10+$12)/$4
print $1, $2, file1arg[3], file1arg[4], file1arg[8], \
file1arg[10], file1arg[12], pct_file1, \
$3, $4, $8, $10, $12, pct_file2, pct_file1-pct_file2
} else printf "(%s,%s) in file2 but not file1.%s", $1, $2, ORS
}' treated.bam.tsv untreated.bam.tsv > awkoutput.bam.tsv
Isso recupera a linha do arquivo1 (de file1line
)
e passa para split
para dividir em seus valores constituintes 23,
que são armazenados no array file1arg
.
Então é possível usar file1arg[3]
, file1arg[4]
,…,
a maneira como você estava usando array[$3]
, array[$4]
,…