parsing out in bash

1

meu arquivo se parece com isso

//
[297]((((21:0.125204,20:0.125204):0.00994299,(28:0.0790047,(7:0.0146105,5:0.0146105):0.0643943):0.0561423):0
segsites:
positions: 1 2 4 6 9 10 45 67 78 89 
01010101010101010101010101011111010101

Eu precisaria analisá-lo em três arquivos diferentes

//
[297]((((21:0.125204,20:0.125204):0.00994299,(28:0.0790047,(7:0.0146105,5:0.0146105):0.0643943):0.0561423):0

então

 segsites:
    positions: 1 2 4 6 9 10 45 67 78 89 

um

 01010101010101010101010101011111010101

o problema é que não há um número fixo de linhas começando com os colchetes e assim por diante. a linha final poderia começar com 0 ou 1 e isso é um problema, pois eu não sei como dizer ao grep para procurar 0 ou 1. Eu precisaria grep para o []. então os segsites e a linha abaixo que inclui a pos e depois a linha numérica com 01

    
por user3069326 26.04.2015 / 14:03

2 respostas

3

Bem, em awk :

awk '/^[01]+$/ {print > "third-file"; next} 
 /(segsites|positions)/ {print > "second-file"; next} 
 {print > "first-file"}' input-file

Considerando três casos:

  • Uma linha contendo apenas 0s e 1s ( /^[01]+$/ )
  • Uma linha contendo segsites ou positions : /(segsites|positions)/
  • Todas as outras linhas

Em cada caso, imprimimos em um arquivo diferente e prosseguimos para a próxima linha. Altere "third-file" , "second-file" , "first-file" para nomes apropriados (mantenha as aspas).

    
por muru 26.04.2015 / 14:25
1

Usando grep com PCRE [ -P ] e modificador Dotall [ (?s) ]:

1ª parte:

$ grep -Poz "(?s)^.*?(?=\nsegsites:)" file.txt 
//
[297]((((21:0.125204,20:0.125204):0.00994299,(28:0.0790047,(7:0.0146105,5:0.0146105):0.0643943):0.0561423):0

2ª parte:

$ grep -Poz "(?s)segsites.*?(?=\n[10]+$)" file.txt 
segsites:
positions: 1 2 4 6 9 10 45 67 78 89 

No caso da terceira parte, apenas grep será (se você tiver apenas uma linha):

$ grep -E "^[01]+$" file.txt
01010101010101010101010101011111010101

Se você não tiver certeza (linhas únicas / múltiplas):

$ grep -Poz "(?<=\n)(?:[10]|\n)*(?=\n$)" file.txt 
010101010101010101010101010111110101011
01010101010101010101010101011111010101010

$ grep -Poz "(?<=\n)(?:[10]|\n)*(?=\n$)" file.txt 
010101010101010101010101010111110101011

Explicações:

  • grep -P representa PCRE (expressões regulares compatíveis com Perl)

  • grep -o selecionará apenas a parte correspondente

  • grep -z fará com que as linhas sejam separadas por ASCII NUL em vez de novas linhas

  • (?s) é chamado de modificador Dotall, usando esse caractere (incluindo quebras de linha) pode ser correspondido por .

  • (?=) is Positivo lookahead, representa o que segue a nossa correspondência

  • (?<) é lookbehind positivo representa o que precede nossa correspondência

por heemayl 26.04.2015 / 17:28