Como usar o sed para encontrar as strings entre dois padrões?

0

Eu tenho conteúdo de arquivo como este:

aaa accounting exec ...
aaa accounting exec ...
aaa accounting commands ..
aaa accounting commands ..
aaa accounting commands ..
aaa accounting commands ..
aaa accounting commands ..
aaa accounting commands ..
aaa accounting network ..
aaa accounting connection ..
aaa accounting system ..
!
aaa accounting exec default
 action-type start-only
 group tacacs+
!
aaa accounting exec default stop-only group tacacs+

A saída deve ser assim:

aaa accounting exec default ..
aaa accounting exec default
 action-type start-only
 group tacacs+
!
aaa accounting exec default ..

Eu tentei seguir o comando sed :

sed -n '/aaa accounting exec default/,/!/p' AboveFileContent.txt

Mas não produz o que eu quero.

Qual seria a solução? Eu tentei usar awk também, mas o mesmo resultado está chegando. Qual seria o comando para obter o resultado exato?

    
por snoop 23.12.2014 / 15:12

2 respostas

2

Eu usaria o awk para isso:

awk '
    /aaa accounting exec default/ {print; exec=1; next} 
    exec {
        if (/^ /) {print; next} else if (/^!/) {print}
        exec=0
    }
' filename

Passando o padrão, use a opção -v do awk e, em seguida, o operador de correspondência de padrões ~ :

awk -v patt='aaa accounting exec default' '
    $0 ~ patt {print; exec=1; next} 
    exec {
        if (/^ /) {print; next} else if (/^!/) {print}
        exec=0
    }
' filename
    
por glenn jackman 23.12.2014 / 15:59
0

Você está tentando obter dados estruturados no formulário:

aaa ...
 ...
 ...
!

Você precisa tornar o sed ciente de que os blocos recuados são importantes. Uma maneira crua pode ser escrever um loop em sed :

sed -n '
# Create a label named 'start'
:start
# If the line matches the beginning of a block, 
# jump (branch) to the label named section
/aaa accounting exec default/ b section
# If we didn't branch, get the next line
n
# Jump back to the start label
b start
# The label named section
:section
# print the line
p
n
# Keep looping to section for the lines we need
/^ /,/!/ b section
# If we don't have any more lines to loop on, 
# jump back to the beginning
b start
'

Em uma linha:

$ sed -n ':start; /aaa accounting exec default/ b section; n; b start; :section; p; n; /^ /, /!/ b section; b start' test.txt
aaa accounting exec default start-stop group tacacs+
aaa accounting exec default
 action-type start-only
 group tacacs+
!
aaa accounting exec default stop-only group tacacs+

Isso pode ser feito de maneira mais legível usando awk , perl ou python , eu acho.

    
por muru 23.12.2014 / 15:48