2016-12-19 1 views
2

У меня есть файл config.yaml, который содержит среди других значений следующий список брокеров kafka, который я хочу удалить из конфигурации с помощью сценария bash.bash - sed запрос для редактирования файла yaml

kafka.brokers: 
    - "node003" 
    - "node004" 

Я делаю это в настоящее время, вызывая VI внутри скрипта, используя следующую команду:

vi $CONF_BENCHMARK/config.yaml -c ":%s/kafka.brokers:\(\n\s*-\s".*"\)*/kafka.brokers:/g" -c ':wq!' 

Я понимаю, что СЭД является более подходящим инструментом для выполнения той же задачи, но когда Я пытаюсь перевести указанное выше регулярное выражение на sed, он не работает.

sed -i -e "s/kafka.brokers:\(\n\s*-\s".*"\)*/kafka.brokers:/g" $CONF_BENCHMARK/config.yaml 

Я делаю что-то неправильно?

+0

'СЭД является более подходящим tool' -> Нет, YAML парсер является более подходящим инструментом :-) YAML является довольно сложным, и не все подходят быть изменены одноранговой с сценариями оболочки и т. п. – Carpetsmoker

ответ

1

Как другие отметили, вы должны быть явными, чтобы СЭД работать с многократно линиями ,

Настоящий ответ заключается в использовании AWK a beautiful answer is provided by karakfa. Но для образовательных целей я обеспечит SED ответ:

sed ' 
    /kafka.brokers/ { 
    :a 
    $be 
    N 
    /\n[[:space:]]*-[[:space:]]"[^\n]*"[^\n]*$/ba 
    s/\n.*\(\n\)/\1/ 
    P;D 
    :e 
    s/\n.*// 
    } 
' input 

В основном СЭД будет держать добавить строки в шаблоне пространства с момента, когда kafka.brokers вплоть до \n[[:space:]]*-[[:space:]]"[^\n]*"[^\n]*$ не найдено.

Это оставит шаблонное пространство с одной задней линией его, то есть:

kafka.brokers:\n - "node003"\n - "node004"\nother stuff$ 

Замена всех \n.*\(\n\) с новой строкой оставляет следующий шаблон пространство:

kafka.brokers:\nother stuff$ 

P;D напечатает первый линии из пространства шаблонов, а затем перезапустить цикл с восстановлением пространства шаблонов. Изготовление входной поддержки:

kafka.brokers: 
    - "node003" 
    - "node004" 
kafka.brokers: 
    - "node005" 
more_input 
1

Ваш шаблон Vim соответствует нескольким строкам, но sed работает по очереди. (То есть сначала он пытается сопоставить ваш шаблон с kafka.brokers: и терпит неудачу, затем он пытается сопоставить - "node003" и т. Д.). Ваш инстинкт использовать что-то, кроме Вима, был прав, но sed, вероятно, не лучший инструмент для работа здесь.

This answer решает проблему соответствия многострочных шаблонов с sed более подробно.

Моей личной рекомендацией было бы использовать язык сценариев, такой как Python или Perl, для обработки сложного соответствия шаблону. Например, вы можете запустить команду Python с python -c <command>, как и с Vim, или вы можете написать небольшой скрипт Python, который вы вызываете из своего сценария Bash. Это немного сложнее, чем sed однострочный, но это, вероятно, сэкономит вам много отладки и упростит ваш скрипт и изменит его.

+0

Я пробовал perl как 'perl -pi -e 's/kafka.brokers: \ (\ n \ s * - \ s". * "\) */Kafka.brokers:/g" config.yaml', но это делает похоже, не работает. Надеюсь, python работает для меня. –

+0

@andlrc Я пытаюсь заменить место в файле 'config.yaml', как показывает мой код в приведенном выше комментарии. Запуск результатов вашего предложения 'Невозможно открыть perl-скрипт 's/kafka ....": Нет такого файла или каталога ' –

+0

@HaseebJaved' perl -p0e' ... ''будет обрабатывать весь файл за один раз. Используйте '-pi -0e' для редактирования inplace. – andlrc

4

awk на помощь!

sed является линия на основе, это должно работать ...

$ awk 's{if(/\s*-\s*"[^"]*"/) next; else s=0} /kafka.brokers:/{s=1}1' file 

Объяснение

if(/\s*-\s*"[^"]*"/) next если шаблон соответствует перейти к следующей строке
s{if(/\s... шаблон проверки, если только ы установлен
/kafka.brokers:/{s=1} когда заголовок видел комплект s
1 стенография для печати линий (если не пропускается)
s{... else s=0} если s был установлен, но модель не найдена, сбросьте S

+0

Не могли бы вы объяснить, как это работает? Возможно, мне придется немного изменить его, прежде чем я смогу его использовать. –

+0

Btw Я попробовал ваше решение на примере, приведенном выше, и он не работает. –

+0

он не работает, не очень описателен ... Ничего не напечатано? Ничего не фильтруется? Удаленный входной файл? – karakfa