AWK Printing Lines e descartando alguns deles

0

Eu sou um novato AWK. Eu tenho um seguinte motivo em um arquivo enorme.

~ Gradients ~
~   x               y            z      ~
~~ 
~ H         1      0.00781      0.00108      0.00038 ~
~ H         2      0.01271     -0.01507      0.02839 ~
~ C         1     -0.05015     -0.01803      0.01588 ~
~ O         1      0.01733      0.03089     -0.04611 ~
~ O         2      0.01230      0.00114      0.00147 ~

Eu preciso extrair esses números (x y z):

0.00781      0.00108      0.00038
0.01271     -0.01507      0.02839
-0.05015     -0.01803      0.01588
0.01733      0.03089     -0.04611 
0.01230      0.00114      0.00147

Eu escrevi o seguinte script:

awk '/z ~/ {for(i=-2; i<=3; i++) {getline; print $4, $5, $6}}' filename

Mas isso me dá uma linha em branco devido à linha "~~".

Eu gostaria de ignorar essa linha e obter apenas as colunas xyz

xyz
xyz
xyz
xyz 

sem linhas em branco ...

Alguém poderia me ajudar, por favor?

    
por Mr Floppy 06.06.2017 / 04:22

2 respostas

1

Você pode explicar com mais clareza exatamente o que você está tentando fazer? Parece que você está tentando imprimir os valores x, y e z ( $4 , $5 e $6 ) das próximas seis linhas depois de uma linha que contém um literal z seguido por um ~ . Mas isso não faz muito sentido - a menos que você tenha um padrão de repetição de um cabeçalho, cinco linhas de dados, outro cabeçalho, outras cinco linhas de dados, etc - e, se for esse o caso, você realmente precisa explicar isso. E se é isso que você está tentando fazer, por que você está fazendo isso? com for(i=-2; i<=3; i++) em vez de for(i=1; i<=6; i++) .

E isso não é uma boa maneira de usar getline .

Se eu entender corretamente seu objetivo, tudo que você precisa é

awk 'NF==7 {print $4, $5, $6}' filename

Isso imprimirá os 4º, 5º e 6º campos (x, ye z) de cada linha que tem sete campos e ignora todo o resto.

    
por 06.06.2017 / 05:13
0

Sua pergunta é confusa porque seus dados parecem ter uma linha de cabeçalho terminando com z      ~ e seu comando parece procurar por /z ~/ , então eles não devem corresponder. Mas talvez seja zTab~ em ambos os lugares.

Para simplificar, usarei /z *~/ para corresponder a z seguido por qualquer número de espaços, seguido por um ~ . Vá em frente e continue usando qualquer string de pesquisa para você.

Você esclareceu em um comentário que deseja para imprimir os valores x, y, andz da 2ª, 3ª, 4ª, 5ª e 6ª linhas depois de uma linha de cabeçalho que contém o z   ~ . Aqui está uma maneira de fazer isso em awk :

awk '
        /z *~/          { counter=1; next }
        counter > 1     { print $4, $5, $6 }
        counter == 6    { counter = 0 }
        counter > 0     { counter++ }
    ' filename
  • /z *~/ { counter=1; next } diz: quando vemos uma linha que contém o z   ~ , definimos um contador como 1. Isso será usado para contar as próximas seis linhas. Use o comando next para não processar mais nada nesta linha - nós não queremos considerar a possibilidade de imprimir a linha de cabeçalho.
  • counter > 1 { print $4, $5, $6 } imprime x, y e andz das linhas onde counter > 1 . Observe que isso não está testando counter > 0 ou counter >= 1 , então ele pula a primeira linha após o cabeçalho, e imprime as linhas 2ª, 3ª, 4ª, 5ª e 6ª.
  • counter == 6 { counter = 0 } diz, quando counter atinge 6, terminamos com esse "motivo", então definimos counter para zero.
  • counter > 0 { counter++ } simplesmente diz isso, contanto que estejamos em um "motivo", devemos incrementar (adicionar um a) o counter para cada linha.
por 06.06.2017 / 22:57

Tags