Удалите несколько строк из файла, когда текст будет найден

Я видел несколько ответов для удаления одной строки с sed или grep, но я нуждаюсь, чтобы искать строку, удалить ту и 2 строки продолжения. Например, в файле ~/.profile У меня есть строки как:

#Set environment variable
export NAME=value
# (blank line here)

Таким образом, я хотел бы искать #Set environment variable, и удалите его, затем удалите следующую строку export NAME=variable (содержание не должно иметь значения), и следующая пустая строка. export имена переменной являются динамичными, но комментарий всегда будет тем же. Мог быть другой export переменные без вышеупомянутого комментария, который я не хочу удалять.

Как я могу выполнить это?

4
задан 17 June 2015 в 17:38

3 ответа

С более новой версией GNU sed (идет с Ubuntu), можно соответствовать новым строкам буквально:

sed -z 's/#Set environment variable\nexport [^\n]\+\n\n//g' file.txt
  • -z опция будет рассматривать строки входных файлов, как завершено ASCII NUL, а не новая строка, таким образом мы можем использовать \n соответствовать новым строкам

  • #Set environment variable\n будет соответствовать первой строке (новой строке)

  • export [^\n]\+\n будет соответствовать второй строке, запускающейся с export

  • Поскольку третья строка является пробелом просто \n сделаю

  • Затем мы заменяем целый шаблон, соответствовавший пробелу для хранения желаемой части

В Вас хочу перезаписать файл с измененным содержанием:

sed -zi.bak 's/#Set environment variable\nexport [^\n]\+\n\n//g' file.txt

Исходный файл будет сохранен как file.txt.bak, если Вы не хотите, это просто использует sed -zi.

Вот тест:

$ cat file.txt 
#Set environment variable
export NAME=value
#some text

#Set environment variable
export NAME=value

check
value

export some=value

#Set environment variable
export NAME=value

foo bar



$ sed -z 's/#Set environment variable\nexport [^\n]\+\n\n//g' file.txt 
#Set environment variable
export NAME=value
#some text

check
value

export some=value

foo bar
4
ответ дан 1 December 2019 в 09:22

Очень легко сделать, это со стандартным sed's удаляет команду:

cp ~/.profile ~/.profile.bak
sed '/#Set environment variable/,+2 d' <~/.profile.bak >~/.profile

Быть осторожным с Вашим ~/.profile

2
ответ дан 1 December 2019 в 09:22

Хотя Ваш вопрос заставляет его быть похожим, Вы ищете командную строку способ сделать это, если бы я был в Вашей ситуации и только хотел сделать это для одного или двух файлов, я использовал бы emacs.

emacs имеет возможность изучения последовательности нажатий клавиш и затем повторения их так много раз, как Вы хотите. Таким образом в Вашем случае я открыл бы ~/.profile в emacs и затем тип

C-x ( C-s #Set environment variable C-a C-k C-k C-k C-x )

[который, в словах, делает это: C-x (означает, "начинают изучать это"; C-s означает "поиск", таким образом мы ищем #Set переменную среды, и затем C-a значит "назад для начала строки, и три C-k, средние ", удаляют эту строку", и наконец C-x) означает "остановку, изучая это".]

После того, как те команды были введены, как только, emacs удалил три строки, но он также изучил, как сделать это наизусть, таким образом, Вы можете теперь тип

C-x e

, и он сделает это снова, или

C-u 100 C-x e

, и он сделает это 100 раз (или остановится, когда он не сможет больше находить строки с "#Set переменная среды" в).

преимущество использования emacs состоит в том, что Вы видите, что Ваши редактирования происходят "живые", и для параноидального человека как я, кто боится, что одна sed опечатка может удалить много материала, который я не хотел удаленный, это делает меня намного более счастливым [вещи момента идут не так, как надо в emacs, можно просто пойти назад и зафиксировать их с C-_].

0
ответ дан 1 December 2019 в 09:22

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

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