Estou tentando substituir VEVENT
as VTODO
entradas em um arquivo .ics se ele corresponder ao atual date
em outra linha (foi exportado incorretamente):
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20220340T140000
END:VEVENT
BEGIN:VEVENT
DTSTART:20230620T193700
END:VEVENT
BEGIN:VEVENT
DTSTART:20210210T193800
END:VEVENT
END:VCALENDAR
A segunda entrada VEVENT tem hora atual, então deve se tornar:
BEGIN:VTODO
DTSTART:20230620T193700
END:VTODO
Há mais entradas entre BEGIN:VEVENT
as END:VEVENT
linhas e, eu as editei para maior clareza.
Eu tentei isso com sed, mas os intervalos escolhem a primeira ocorrência de VEVENT no arquivo inteiro, não a primeira ocorrência depois (ou antes) do padrão correspondente, então ele substitui todos eles.
sed -i "/BEGIN:VEVENT/,/DTSTART:$(date +%Y%m%dT%H%M)/{s/VEVENT/VTODO/}" org.ics
Eu estava tentando adaptar para outra pergunta aqui, que achei relevante: Encontre uma string e substitua outra string depois que a primeira for encontrada
sed -n "/DTSTART:$(date +%Y%m%dT%H%M)/,${/END:VEVENT/{x//{x b}g s/VEVENT/VTODO/}}" org.ics
mas não funcionou de jeito nenhum:
sed: -e expression #1, char 25: unexpected
,'`
Então o seguinte deve funcionar:
Explicação:
H
: Acrescenta ao espaço de espera que cria uma espécie de buffer (espaço), então fazemos correspondência de padrão/BEGIN:VEVENT/h
e armazená-lo no espaço de retenção, então agora executamos outra correspondência de padrão/END:VEVENT/!d
e se o padrão não corresponder, exclua-o.x;
As trocas mantêm o espaço com o espaço padrão, então agora temos as linhas de que precisamos no espaço padrãoFinalmente, substitua a linha
DTSTART...
se corresponder à data. Sos/.../.../g
é executado apenas se houver uma correspondência./DTSTART:'"$(date +%Y%m%dT%H%M)"/s/VEVENT/VTODO/g
Atualizar
Usando robustamente qualquer awk em qualquer shell em cada caixa Unix:
A única maneira de falhar seria se você pudesse ter alguma outra seção em sua entrada que possa conter linhas que correspondam a qualquer uma das linhas BEGIN:, END: ou DSTART:, mas duvido que isso possa ser válido em sua entrada - você 'd tem que nos mostrar como é especificado se for.
O importante sobre a solução acima é que ela está comparando linhas literais inteiras com as strings de destino, não apenas fazendo correspondências parciais onde quer que elas ocorram na entrada.
Não está resolvendo, mas apenas a dica:
Onde
sed
o comando adiciona: (dois pontos) no final de cada linha,RS="BEGIN"
define o RowSeparator para a palavra-chave BEGIN (é por isso que ele descarta!),FS=":"
define o FieldSeparator como ":" . Em cada "linha" (da palavra-chave BEGIN para o próximo BEGIN, melhor dito "registro") os campos são copiados para os membros da matrizAA[i]
começando com i=2, porque o AA[1] tem que ser o BEGIN descartado. Ao verificar a palavra-chave DTSTART e a data atual, altere o VEVENT para VTODO, se necessário. Após a verificação da linha, o array AA[] é impresso e com : como separador.Essa é apenas a dica, não testei. Você tem que depurar e ajustar por si mesmo. Ou seja, você pode limpar o final: se for indesejado.
Podemos ter uma solução assim no TXR :
Isso, por si só, reescreverá todas as entradas para
VTODO
:Podemos vincular as variáveis
date
etime
da linha de comando:Agora isso só corresponde e reescreve a segunda entrada.
Versão bonita: