Как использовать sed для нахождения строк между 2 шаблонами?

У меня есть содержание файла как это:

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+

Вывод должен быть похожим на это:

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

Я попробовал следующее sed команда:

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

Но это не продукт, что я хочу.

Каково было бы решение? Я попытался использовать awk также, но тот же результат прибывает. Какова была бы команда для получения точного вывода?

0
задан 13 October 2016 в 20:23

2 ответа

Я использовал бы awk для этого:

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

При передаче шаблона используйте awk's -v опция и затем шаблон соответствуют оператору ~:

awk -v patt='aaa accounting exec default' '
    $0 ~ patt {print; exec=1; next} 
    exec {
        if (/^ /) {print; next} else if (/^!/) {print}
        exec=0
    }
' filename
2
ответ дан 6 October 2019 в 06:06

Вы пытаетесь структурировать данные в форме:

aaa ...
 ...
 ...
!

необходимо сделать sed знающий, что блоки с отступом имеют значение. Сырой путь мог бы состоять в том, чтобы записать цикл в 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
'

В одной строке:

$ 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+

Это могло быть сделано в более читаемом способе использовать awk, perl или python, я предположу.

0
ответ дан 6 October 2019 в 06:06

Другие вопросы по тегам:

Похожие вопросы: