Я видел несколько ответов для удаления одной строки с sed
или grep
, но я нуждаюсь, чтобы искать строку, удалить ту и 2 строки продолжения. Например, в файле ~/.profile
У меня есть строки как:
#Set environment variable
export NAME=value
# (blank line here)
Таким образом, я хотел бы искать #Set environment variable
, и удалите его, затем удалите следующую строку export NAME=variable
(содержание не должно иметь значения), и следующая пустая строка. export
имена переменной являются динамичными, но комментарий всегда будет тем же. Мог быть другой export
переменные без вышеупомянутого комментария, который я не хочу удалять.
Как я могу выполнить это?
С более новой версией 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
Очень легко сделать, это со стандартным sed's удаляет команду:
cp ~/.profile ~/.profile.bak
sed '/#Set environment variable/,+2 d' <~/.profile.bak >~/.profile
Быть осторожным с Вашим ~/.profile
Хотя Ваш вопрос заставляет его быть похожим, Вы ищете командную строку способ сделать это, если бы я был в Вашей ситуации и только хотел сделать это для одного или двух файлов, я использовал бы 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-_
].