usando grep para linhas específicas em arquivos de texto

3
     2              METEOROLOGICAL DATA                         VERSION /      
     8    PR    TD    HR    ZW    ZT    WD    WS    RI      # / TYPES OF   MOD/TYPE/ACC 
  3979316.8350  1050313.7180  4857065.7030      592.1910 PR SENSOR POS XYZ/H           
                                                            END OF HEADER 
 10  1  1  0  0 15  927.9    4.3   99.1                
 10  1  1  0  1 15  927.9    4.3   99.1                
 10  1  1  0  2 15  927.9    4.3   99.1                
 10  1  1  0 15 15  927.9    4.2   99.1               
 10  1  1  0 16 15  927.9    4.2   99.0                
 10  1  1  0 30 15  927.7    4.1   99.1                
 10  1  1  0 31 15  927.7    4.1   99.1                
 10  1  1  0 45 15  927.5    4.1   99.1                
 10  1  1  0 46 15  927.5    4.0   99.1                
 10  1  1  1  0 15  927.4    4.1   99.1                
 10  1  1  1  1 15  927.4    4.1   99.1                

Neste exemplo de dados de texto, como posso extrair todos os valores 0,15,30,45 na quinta coluna de dados numéricos ordenada, após a parte " END OF HEADER " da seguinte forma:

10  1  1  0  0 15  927.9    4.3   99.1  
10  1  1  0 15 15  927.9    4.2   99.1 
10  1  1  0 30 15  927.7    4.1   99.1 
10  1  1  0 45 15  927.5    4.1   99.1
10  1  1  1  0 15  927.4    4.1   99.1 
    
por deepblue_86 17.08.2016 / 10:57

3 respostas

2

Você pode fazer isso usando sed e awk :
(supondo que o texto do seu assunto esteja em um arquivo chamado example.txt )

sed -n '/END OF HEADER/,${
/END OF HEADER/d
p
}' example.txt | awk '( == 0 ||  == 15 ||  == 30 ||  == 45)'

Attribution - o comando awk foi obtido do comentário do steeldriver

Explicação

Sed

  • ignora tudo até /END OF HEADER/
  • /END OF HEADER/d significa excluir a linha que contém /END OF HEADER/ do espaço padrão e, como não está mais no espaço padrão, o próximo comando p não fará nada
  • p - imprime cada linha conforme é puxada para dentro do espaço padrão

Awk

  • se a coluna 5 for 0 ou 15 ou 30 ou 45, imprima-a
por the_velour_fog 17.08.2016 / 11:56
4

Um rápido forro seria:

$ awk ' == '0' ||  == '15' ||   == '30' ||   == '45' {print}' test.txt

Como fedorqui mencionado no comentário abaixo e ainda mais rápido um forro é:

$ awk ' ~ /^(0|15|30|45)$/' test.txt

Sintaxe explicada:

  - the desired column from the text.
~   - the match symbol... matching was between the two slashes (/).
^/$ - the regex symbols indicating the beginning and end of the field.
|   - the or specifier for either item in the "()" group.

O cabeçalho é filtrado aceitando apenas as linhas que correspondem aos itens após a correspondência ~ critérios.

    
por L. D. James 17.08.2016 / 12:20
3

É perfeitamente possível em grep , embora awk seja a ferramenta para dados separados por campos.

com grep :

grep -E '^10[[:blank:]]+([^[:blank:]]+[[:blank:]]+){3}(0|15|30|45)[[:blank:]]' file.txt
  • Corresponde 10 no início, ([^[:blank:]]+[[:blank:]]+){3} corresponde aos próximos 3 campos e, em seguida, corresponde ao quinto campo para os desejados

Se você usa PCRE ( -P ), pode substituir [:blank:] por \s , fica bem nos olhos:

grep -P '^10\s+([^\s]+\s+){3}(0|15|30|45)\s' file.txt     

Exemplo:

$ cat file.txt                                        
    2              METEOROLOGICAL DATA                         VERSION /      
    8    PR    TD    HR    ZW    ZT    WD    WS    RI      # / TYPES OF   MOD/TYPE/ACC 
 3979316.8350  1050313.7180  4857065.7030      592.1910 PR SENSOR POS XYZ/H           
                                                           END OF HEADER 
10  1  1  0  0 15  927.9    4.3   99.1                
10  1  1  0  1 15  927.9    4.3   99.1                
10  1  1  0  2 15  927.9    4.3   99.1                
10  1  1  0 15 15  927.9    4.2   99.1               
10  1  1  0 16 15  927.9    4.2   99.0                
10  1  1  0 30 15  927.7    4.1   99.1                
10  1  1  0 31 15  927.7    4.1   99.1                
10  1  1  0 45 15  927.5    4.1   99.1                
10  1  1  0 46 15  927.5    4.0   99.1                
10  1  1  1  0 15  927.4    4.1   99.1                
10  1  1  1  1 15  927.4    4.1   99.1    

$ grep -E '^10[[:blank:]]+([^[:blank:]]+[[:blank:]]+){3}(0|15|30|45)[[:blank:]]' file.txt
10  1  1  0  0 15  927.9    4.3   99.1                
10  1  1  0 15 15  927.9    4.2   99.1               
10  1  1  0 30 15  927.7    4.1   99.1                
10  1  1  0 45 15  927.5    4.1   99.1                
10  1  1  1  0 15  927.4    4.1   99.1                

$ grep -P '^10\s+([^\s]+\s+){3}(0|15|30|45)\s' file.txt                         
10  1  1  0  0 15  927.9    4.3   99.1                
10  1  1  0 15 15  927.9    4.2   99.1               
10  1  1  0 30 15  927.7    4.1   99.1                
10  1  1  0 45 15  927.5    4.1   99.1                
10  1  1  1  0 15  927.4    4.1   99.1        
    
por heemayl 17.08.2016 / 12:30