Eu tenho vários arquivos ICS que contêm algo como:
...
PRIORITY:4
DESCRIPTION:this
was
a
triumph
COMPLETED:20180101T160000
...
Estou interessado em abordar a DESCRIPTION
chave. A chave DESCRIPTION
pode ocorrer em qualquer lugar no arquivo ICS. Nem sempre é seguido pela chave COMPLETED
.
Usando ed
, eu faria assim:
/DESCRIPTION/;/^[^ ]/-1p
o que resulta em:
DESCRIPTION:this
was
a
triumph
No entanto, sed
não parece ter essa capacidade:
sed -n '/DESCRIPTION/,/^[^ ]/-1p' filename
resulta em
sed: -e expressão #1, char 22: comando desconhecido: `-'
Existe uma maneira de fazer o que eu quero usando sed
?
Resolvendo este problema específico
Este problema pode ser resolvido por:
sed -n '/DESCRIPTION:/,/^\S/ { /\(DESCRIPTION\|^\s\)/p }' example.ics
Mas isso parece muito pesado e verboso.
awk
também parece não suportar /begpat/,/endpat/-1
, então você terminaria com algo como:
BEGIN { endpat = "^(DESCRIPTION|\\s)" }
/^DESCRIPTION/, $0 !~ endpat {
if ($0 ~ endpat) {print}
}
Você estava bem perto:
Faria o que você quiser. Por quê?
/start/,/stop/!d
//d
faria isso (o padrão vazio//
corresponde ao último padrão, portanto, a/stop/
linha)p
rint-lo antes e você obtém o comando que eu mostrei (novamente usando o padrão vazio)Atualização com diferentes abordagens
Em seu comentário, você chamou isso de "solução alternativa", o que é de algum ponto de vista. E, na verdade, para mim, eu escolheria uma
sed
abordagem diferente e mais ish:Isso deve parecer natural para os
sed
amantes, mas talvez estranho à primeira vista para alguns. Segue a abordagem do " desejo-que-poderia-lembrar ". O que é aquilo? Cada vez que você chega a uma linha sem recuo, você pensa "Eu gostaria de poder lembrar as linhas anteriores, se elas valem a pena ser impressas". Então simplesmente assumimos que os temos em nossa memória, o espaço de espera, para que possamos simplesmentex
alterar o espaço de padrão e manter o espaço ed
excluí-lo se não começar comDESCRIPTION
(se começar com, será impresso por padrão).O bom
x
é que cada linha não recuada estará no espaço de espera automaticamente, então só precisamos adicionar as linhas recuadas ao espaço de espera comH
. Isso o que a/^ /{H;d;}
peça faz (d
é evitar saída ou processamento adicional para essas linhas).Agora, o oposto é o que um programador faria. Eles provavelmente fariam um loop assim:
Ou seja, largue tudo até encontrarmos a palavra-
DESCRIPTION
chave, então inicie um loop para coletar linhasN
e faça um loop até que haja uma linha com um non-space\n[^ ].*
. Nesse caso, remova essa última linha (mais uma vez aproveitando o padrão vazio).Isso também funciona, mas essa não é a maneira típica de fazer as coisas no
sed
.Sim, o sed suporta intervalos de endereços como este:
No seu caso, tente usar
-E
a opção para expressões regulares estendidas.