Primeiro, extraia o campo que você deseja do Arquivo 2:
value="$(awk -F, 'NR==1{print $3;exit}' file2)"
Em seguida, conecte-o ao código de substituição do Arquivo 1:
awk '{$11 = v} 1' v="$value" file1
Eu quero substituir uma coluna em um arquivo por um único valor de outro arquivo usando o unix.
O arquivo 1 é um arquivo pdb, estruturado assim:
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -1.00 H
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -1.00 H
Eu quero substituir o número da coluna 11 por um valor único que é armazenado em outro arquivo (Arquivo 2) que se parece com isto:
[1, 27, -81.883, 4.0]
[3, 38, -66.122, 12.0]
[3, 57, -62.134, 12.0]
Eu quero que o valor do Arquivo 2 (coluna 3 da linha 1) seja o da coluna 11 do Arquivo 1, para que o Arquivo 1 seja assim:
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.88 H
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.88 H
Eu posso substituir a coluna 11 do Arquivo 1 por um único valor (2 neste caso) usando:
awk '{$11=2}1' File1
e eu encontrei código como este de link
awk 'FNR==NR{a[NR]=$3;next}{$2=a[FNR]}1' f2 f1
No entanto, acredito que eu deveria estar usando uma combinação de awk e sed para obter o valor desejado do Arquivo 2 para o Arquivo 1.
O código abaixo me dá a primeira linha da coluna 11:
awk 'FNR==1{print $11}'
Eu simplesmente não consigo descobrir como combinar as duas coisas.
Não consigo pesquisar por valor porque os valores mudam com cada conjunto de dados que eu tenho (centenas de arquivos pdb para modificar).
Alguém pode ajudar?
Ambas as soluções abaixo atrapalham a formatação do meu arquivo pdb, ou seja, eu recebo:
HETATM 1 PA FAD B 600 95.887 47.194 74.387 1.00 -73.248
em vez de
HETATM 1 PA FAD B 600 95.987 47.188 74.293 1.00 -73.248
estou fazendo algo errado ou você tem alguma idéia do porquê?
Primeiro, extraia o campo que você deseja do Arquivo 2:
value="$(awk -F, 'NR==1{print $3;exit}' file2)"
Em seguida, conecte-o ao código de substituição do Arquivo 1:
awk '{$11 = v} 1' v="$value" file1
Como o valor desejado é a terceira coluna da primeira linha de file2
, você pode obter isso com:
$ awk 'NR==1{print $3}' file2
-81.883,
No entanto, isso também inclui a vírgula que, presumivelmente, você não deseja. Para evitar isso, você pode dizer a awk
para usar qualquer espaço ou como delimitadores de campo usando o -F
flag:
$ awk -F", " 'NR==1{print $3}' file2
-81.883
O awk permite que você defina uma variável na linha de comando com a opção -v
:
-v var=val
--assign var=val
Assign the value val to the variable var, before execution of
the program begins. Such variable values are available to the
BEGIN rule of an AWK program.
Assim, você pode executar awk -vfoo="-81.833" {...}
e isso tornaria o valor -81.33
disponível como a variável foo
no script awk. Se você combinar isso com substituição de comando , você pode passar a saída do primeiro comando awk
(o valor desejado) como uma variável (chamada, por exemplo, i
) para um segundo script que substitui o 11º campo pelo valor da variável i
:
$ awk -vi="$(awk -F", " 'NR==1{print $3}' file2)" '{$11=i}1;' file1
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.883 H
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.883 H
Eu não entendo muito bem esse problema, mas vou arriscar uma solução, eu acho.
sed -nse'1!{ :out
1x
s/ */&\n/10
s/^/ /p;t
}
x; s/..*//;t out
g; s/[^ ]* *[^ ]* *//
s/ .*//;p
x; :eat
$d;n;b eat
' file1 file2 file3 file4 |
sed ' /^ /!{h;d;}
s///;N;G
s/\n[^ ]*\(.*\)\n\(.*\)//
'
Isso pode funcionar. Se você tiver um sed
que possa manipular -s
eparate fluxos de arquivos de entrada, ele deverá alternar entre selecionar apenas o campo desejado do arquivo um e gravar apenas aquele campo para todo o arquivo ou marcar e preparar cada saída linha para o próximo arquivo de entrada para que o segundo sed
possa substituir os campos em questão.
Basicamente funciona com pares de arquivos - a partir do primeiro de cada dois arquivos de leitura, ele imprimirá apenas sua coluna de origem e, em seguida, editará essa coluna de origem no segundo de cada par.
Tags text-processing awk sed