Correspondência de RegEx + remoção de linha adicional

0
Então, eu sou muito novo no que eu atualmente me refiro como RegEx "avançado", por favor, me perdoem, é provavelmente muito fácil para vocês, mas eu preciso ser apontado na direção certa, porque agora eu estou lutando.

Eu rastreei os fóruns e websites, incluindo: link ) e não consigo encontrar o que estou procurando ou, pelo menos, o contrário, então inverto isso e obtenho o stdout que eu quero.

Os dados (stdin) são assim:

C:\Users\Maison\Documents\AutoCad_dir
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

E o que eu quero fazer é usar o RegEx, remover todas as linhas com 4 diretórios ou mais e as 10 linhas seguintes (incluindo as CR \ r).

Então, o que resta será algo como isto:

C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

OBSERVAÇÃO : o rótulo do volume (C :) não é constante, nenhum dado com o qual estou trabalhando é absoluto.

É claro que, nos dados reais que possuo, há muito mais linhas semelhantes à que estou tentando apagar.

O melhor que eu tenho até agora é:

 sed '/pattern/I,+11 d' infile

Mas eu não consigo criar um padrão lógico, cada padrão que eu criei até agora apaga todas as linhas, independentemente da contagem de diretórios.

Eu estava relutante em perguntar, mas isso finalmente me permitirá entender o RegEx & GNU sed melhor.

    
por unkn0wn 18.01.2017 / 21:51

2 respostas

2

Exemplo:

sed '/^[A-Z]:\\([^\]\+\\)\{3,\}/,+10d' test.txt

Se você usasse regexps estendidos (especifique -r to sed ), a expressão se tornaria um pouco mais fácil de ser lida, pois você só teria que escapar de \ :

sed -r '/^[A-Z]:\([^\]+\){3,}/,+10d' test.txt

A parte notável é ([^\]+\){3,} , o padrão entre parênteses indica que corresponde a 1 ou mais ocorrências de qualquer caractere, exceto / , seguido por um único / . {3,} informa que o padrão entre parênteses deve ser correspondido pelo menos 3 vezes para que ele corresponda.

    
por 28.03.2017 / 04:07
1

Usando awk (como a pergunta estava usando a tag ):

$ awk -F '\' 'NF > 4 { skip = 11 } --skip < 0 { print }' file.in
C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

Isso trata cada linha como um registro \ -delimited. Se o número de campos no registro for maior que quatro, pulamos este registro e as próximas 10 linhas de entrada definindo skip = 11 . Essa variável é então decrementada para cada linha de entrada, e se seu valor for negativo (o que significa que pulamos as linhas que gostaríamos de pular), nós imprimimos a linha.

O script pode ser encurtado para

$ awk -F '\' 'NF > 4 { skip = 11 } --skip < 0' file.in

Ambas as versões deste script irão falhar (produzir a saída errada) se qualquer outra linha que não a primeira de cada bloco contiver quatro \ ou mais.

    
por 30.08.2017 / 11:11