Как раскомментировать следующую строку с помощью sed - PullRequest
1 голос
/ 01 мая 2019

Я пытаюсь настроить свой файл pacman.conf автоматически при установке Arch с archiso.

Для этого я хочу раскомментировать две строки в файле конфигурации pacman.

Вотвыдержка из рассматриваемого файла:

#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist

Итак, я хочу раскомментировать две строки блока multilib, а не блок тестирования multilib!

Чтобы раскомментировать первую строкублок с помощью sed прост:

sed -i 's/#\[multilib]/\[multilib]/g' /etc/pacman.conf

Однако следующая строка точно такая же, как и в предыдущем блоке (и на практике во многих других блоках), так что если я сделаю:

sed -i 's/#Include =/Include =/g' pacman.conf

Будет изменена вся строка, соответствующая шаблону.

Мне нужно только изменить конкретную строку сразу после [multilib] Как я могу это сделать?

Ответы [ 3 ]

3 голосов
/ 01 мая 2019

Когда вы найдете строку #[multilib], прочитайте строку N ew и добавьте ее к пробелу шаблона, и удалите # после строки (\n).

sed '/^#\[multilib]/{N;s/\n#/\n/}' file

Учитывая ваш образец его вывод:

#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
Include = /etc/pacman.d/mirrorlist

Если также является опцией:

awk 'f{sub(/^#/,"");f=0} $0=="#[multilib]"{f=1} 1' file

Таким образом, вам не нужно экранировать символы, активные в регулярных выражениях.

2 голосов
/ 01 мая 2019

sed для s / old / new для отдельных строк, вот и все.С awk:

$ awk '$0=="#[multilib]"{c=2} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

Не требуется экранирования символов, и если вам нужно удалить # из 50 строк вместо 2, просто измените 2 на 50, вам не нужно переписывать свой скрипт!Очевидно, что вы можете параметризовать начальную строку и количество строк, чтобы раскомментировать, если хотите:

$ awk -v beg='#[multilib]' -v num=2 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

$ awk -v beg='#[multilib-testing]' -v num=2 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist

$ awk -v beg='#[multilib-testing]' -v num=5 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist
2 голосов
/ 01 мая 2019

Существует более простое решение sed, которое не требует многострочных методов:

/^#\[multilib]/ {   # Match only the [multilib] line.
  n                 # Then read the next line.
  s/^#//            # ... and delete the comment marker.
}

Тестирование:

▶ cat > FILE <<EOF
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist
EOF
▶ gsed -i '/^#\[multilib]/{n;s/^#//}' FILE

Выход:

▶ cat FILE
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
Include = /etc/pacman.d/mirrorlist
...