imprimir tudo antes / depois da enésima linha correspondente

2

Gostaria de imprimir tudo antes da segunda linha que começa com * i (asterisco, espaço, letra minúscula I) excluindo a linha e tudo depois dessa linha, incluindo a linha separadamente.

Por exemplo, se eu tivesse um arquivo de texto como este:

* misc: go to the park
with your dog 
* important: sell badges
the bigger the pricier
24 left right now
* important: go to the mall
get clothes
* important: finish homework 

Gostaria de imprimir isto primeiro:

* misc: go to the park
with your dog
* important: sell badges
the bigger the pricier
24 left right now

e depois isto:

* important: go to the mall
get clothes
* important: finish homework 

Como posso fazer isso usando sed?

Eu tentei

sed  '/\* [^i]/,$   { /\* [^i]/,$ d}' /path/to/txt/

mas apenas imprime tudo antes da primeira linha de correspondência 1st .

Eu gostaria de ter dois scripts separados para extrair cada parte.

    
por stacko 23.02.2018 / 15:15

2 respostas

2

Eu sugeriria o processamento de awk (que, acredito, será mais flexível e robusto):

awk '/^\* i/ && ++c == 2{ print r ORS; r=""; c=0 }
     { r=(r? r ORS:"")$0 }
     END{ print r }' file

A saída:

* misc: go to the park
with your dog 
* important: sell badges
the bigger the pricier
24 left right now

* important: go to the mall
get clothes
* important: finish homework

Para o seu caso simples atual (sem lógica adicional) - pode ser encurtado para o seguinte:

awk '/^\* i/ && ++c == 2{ print "" }1' file

Para extrair a parte necessária separadamente - ainda com um único comando awk , mas usando o argumento dinâmico part , que aceita o valor condicional 1 (primeira seção, seção anterior) ou 2 (segunda seção, seção seguinte) ).

Esquema:

awk -v part=[12] '/^\* i/ && ++c == 2{ if (part == 1) exit; else f=1 } part == 1 || (part == 2 && f)' FILE

Uso:

- imprima "antes" seção:

$ awk -v part=1 '/^\* i/ && ++c==2{ if (part==1) exit; else f=1 }
>         part==1 || (part==2 && f)' file
* misc: go to the park
with your dog 
* important: sell badges
the bigger the pricier
24 left right now

- imprima "depois de" seção:

$ awk -v part=2 '/^\* i/ && ++c==2{ if (part==1) exit; else f=1 }
>         part==1 || (part==2 && f)' file
* important: go to the mall
get clothes
* important: finish homework
    
por 23.02.2018 / 15:34
0

Você também pode usar o sed, é mais complicado que o awk

cat sedscript.sh

deb=$1
sed 's/.*/'"$deb"'\n&/
:A
/^1/{
N
/\n\* i/!bA
:B
N
/\n\* i[^\n]*$/!bB
s/\n[^\n]*$//
s/[^\n]*\n//
q
}
:C
/^2/{
N
/\n\* i/!bC
:D
N
/\n\* i[^\n]*$/!bD
s/.*\n//
:E
N
bE
q
}
d
' $2

Chame assim:

para a primeira parte

./ sedscript.sh 1 arquivo

para a segunda parte

./ sedscript.sh 2 infiles

    
por 23.02.2018 / 20:06