SED удаляет строки между двумя совпадениями - PullRequest
2 голосов
/ 11 ноября 2011

Я пытаюсь заменить строки между двумя совпадениями шаблон / строка, используя SED, см. Ниже. Мне нужно удалить строки ниже interface GigabitEthernet0/3 до interface GigabitEthernet0/4, но оставить оба имени интерфейса.

interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

результат:

interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

Ответы [ 5 ]

1 голос
/ 24 января 2013
$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3
1 голос
/ 11 ноября 2011

Доход:

$> cat ./text 
interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

Итог:

$> cat ./text | sed '/interface GigabitEthernet0\/3/,/\!/c interface GigabitEthernet0\/3\n!'
interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

Sed может работать с многострочными шаблонами . Мы просто используем команду c, которая изменяет совпавший шаблон (с interface GigabitEthernet0/3 на !) с interface GigabitEthernet0/3 и !.

0 голосов
/ 11 ноября 2011

Основной ответ кажется мне простым:

sed -e "/interface GigabitEthernet0\/3/p" \
    -e "/interface GigabitEthernet0\/4/p" \
    -e "/interface GigabitEthernet0\/3/,/interface GigabitEthernet0\/4/d" "$@"

Печать строк, соответствующих «interface GigabitEthernet0 / 3», и строк, содержащих «interface GigabitEthernet0 / 4»; удалите строки между двумя и включите их.

Единственная возможная проблема заключается в том, что если есть «interface GigabitEthernet0 / 4» и нет предшествующего «интерфейса GigabitEthernet0 / 3», то эта строка будет удвоена. Если это реальная проблема, перейдите к более сложному сценарию:

sed -e "/interface GigabitEthernet0\/3/,/interface GigabitEthernet0\/4/{
        /interface GigabitEthernet0\/3/p
        /interface GigabitEthernet0\/4/p
        d
        }" "$@"

Если вы непреклонны, это должна быть одна строка, используйте точки с запятой, но результат будет неразборчивым.

0 голосов
/ 11 ноября 2011

после публикации я нашел свой ответ: вот мое решение

cat somerouter.config | sed '/interface GigabitEthernet0\/3/,/interface GigabitEthernet0\/4/{/^interface GigabitEthernet0\/4/p;d;}' somerouter.config > somenewerrouter.config 

Тогда я просто добавляю обратно интерфейс 0/3 с помощью

sed -e '/interface\ GigabitEthernet0\/4/ i\
interface\ GigabitEthernet0\/3\
 description\ NOT USED\
 shutdown\
!' $filesw.tmp.1 > $filesw.tmp.2
0 голосов
/ 11 ноября 2011

Это может работать для вас:

sed -e '\#^interface GigabitEthernet0/3#,/^!/{//!d}' input_file

или как вы описали это в вопросе:

sed -e '\#^interface GigabitEthernet0/3#,\#^interface GigabitEthernet0/4#{//!d;/4/s/^/!\n/}' input_file

при условии, что вы хотите сохранить ! в строке перед вторым интерфейсом. Если вы не хотите !, пропустите /4/s/^/!\n/ из последнего бита команды sed

...