O título deve ser: Remove all lines between two similar patterns, including the line of the starting pattern. if another specific pattern in between is not matched
. Tornei-o mais curto porque é mais legível para outras pessoas que procuram respostas no Google.
Sobre as perguntas: tenho uma lista de compartilhamentos listáveis e compartilhamentos não possíveis para um computador específico. Quero criar uma lista de todos os computadores que possuem compartilhamentos listáveis e excluir seus compartilhamentos ilegíveis. Mas tropeço em dois problemas. Em primeiro lugar, excluindo corretamente todas as linhas entre dois padrões simulados. Em segundo lugar, como não apagar as linhas entre duas palavras semelhantes se um padrão específico for encontrado.
Minha entrada é
Shares for DED-SHD-ED-5:
[--- Unreadable Shares ---]
ADMIN$
C$
E$
H$
IPC$
Shares for DED-SHD-ED-6:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
[--- Listable Shares ---]
print$
Shares for DED-SHD-ED-7:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
[--- Listable Shares ---]
backup backup2
Shares for DED-SHD-ED-8:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
Shares for DED-SHD-ED-9:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
VBRCatalog
[--- Listable Shares ---]
backup backup2
Consegui retirar todos os compartilhamentos ilegíveis com o seguinte comando awk '/Listable Shares/,/Shares for/' input.txt
, o problema desse comando é que DED-SHD-ED-8
não tem Listable Shares
. Ele remove o computador DED-SHD-ED-9
abaixo e verei os compartilhamentos listáveis de DED-SHD-ED-9
pelo menosDED-SHD-ED-8
Veja o resultado abaixo (sei que falta o nome do primeiro computador da lista, mas isso não é um problema para mim)
[--- Listable Shares ---]
print$
Shares for DED-SHD-ED-7:
[--- Listable Shares ---]
backup backup2
Shares for DED-SHD-ED-8:
[--- Listable Shares ---]
backup backup2
Para resolver esse problema tive a ideia de remover todos os computadores SEM compartilhamentos listáveis antes de executar o awk '/Listable Shares/,/Shares for/' input.txt
. A princípio tentei deletar todas as linhas entre "Compartilhamentos para" e "Compartilhamentos para". Dei uma olhada no fórum e tentei fazer com que as respostas mais simples funcionassem e evitei as complicadas porque elas fogem do meu entendimento no momento. Por exemplo usei este comando sed '/^Shares for/,/^Shares for/{//!d;};' input.txt
e sed '/Shares for/,/:/{//!d;};' input2.txt
aqui ele remove metade das linhas entre os computadores.
Saída
Shares for DED-SHD-ED-5:
Shares for DED-SHD-ED-6:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
[--- Listable Shares ---]
print$
Shares for DED-SHD-ED-7:
Shares for DED-SHD-ED-8:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
Por que retira os dados de apenas metade dos computadores? Eu não vejo por que
Minha próxima ideia foi adicionar uma exclusão ao comando para não excluir as linhas entre "Compartilhamentos para" e "Compartilhamentos para" se o padrão Listable
corresponder nessas linhas. E então exclua os computadores sem mais dados como DED-SHD-ED-5
e DED-SHD-ED-7
. Mas talvez esta não seja a melhor abordagem. Talvez seja melhor excluir a linha do primeiro padrão, caso o padrão "Listável" não seja visto.
Eu adoraria alguma ajuda e insights sobre como processar tudo isso adequadamente.
Resultado esperado:
Shares for DED-SHD-ED-6:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
[--- Listable Shares ---]
print$
Shares for DED-SHD-ED-7:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
[--- Listable Shares ---]
backup backup2
Shares for DED-SHD-ED-9:
[--- Unreadable Shares ---]
ADMIN$
C$
IPC$
VBRCatalog
[--- Listable Shares ---]
backup backup2
Entendimento:
Shares
bloco se esse bloco contiver a stringListable Shares
Depois de incluir
awk
na mistura, geralmente você pode eliminar a necessidade desed
.Uma
awk
ideia (detalhada):Fazendo um test drive:
Isso funciona para você?
shares
sendo o nome do arquivo que escolhi para sua entrada de amostra.Basicamente,
sed
insere uma nova linha antesShares
, se ainda não houver uma - é assim que podemos usar novas linhas como separador de registros (RS="\n\n"
) emawk
. Então é simplesmente uma questão de imprimir apenas registros que contenham a palavraListable
.Usando Raku (anteriormente conhecido como Perl_6)
Raku é uma linguagem de programação da família Perl. Em uma operação que pode ser considerada o inverso da
split
operação destrutiva em um padrão regex, Raku fornece acomb
rotina que permite selecionar elementos de sua escolha. Acima, o arquivo de entrada é dividido em registros selecionando.comb(/^^Shares .*? <?before ^^Shares | $ >/)
registros que possuem:^^Shares
texto de início de linha "Ações",.*?
não-ganancioso qualquer número de caracteres,<?before ^^Shares | $ >
um lookahead positivo que diz para interromper o padrão,?before
o próximo^^Shares
padrão de registro é visto ou$
antes/no final do próprio arquivo.Na segunda operação da cadeia
grep
é usado para retornar apenas os registros que contêm umListable
bloco.Entrada de amostra:
Saída de amostra:
Nota: Muitas vezes é instrutivo observar como uma linguagem representa os dados internamente, então aqui está a saída após
comb
ing em registros separados, mas antesgrep
do ping para o bloco desejado:https://docs.raku.org/language/operators#Operators
https://docs.raku.org/routine/comb
https://docs.raku.org/routine/grep
https://raku.org