У меня есть файл конфигурации, и я хочу заменить строку, содержащую определенную строку, скажем, test :
file.conf
aaa
bbb
ccc
// test
ddd
// test
Моя строка кода не работает, я новичок в sed .
sed -i `s#^//[ \t]test#test#g'
Некоторое руководство?
Прежде всего, я бы рекомендовал избегать использования -i
, поскольку он заменит файлы на месте без подтверждения.
Это рабочая версия того, что вы пытались выполнить, и вывод на стандартный вывод (терминал):
sed 's#^//[ \t]test$#test#g' file.conf
aaa
bbb
ccc
test
ddd
test
При желании можно передать его через меньшее, добавив | less
для возможности разбивки на страницы. через большое количество продукции.
Все вышесказанное очень специфично для последовательности из test
, поэтому, чтобы обобщить, вы можете попробовать это:
sed 's#^//\s\(.*\)$#\1#g' file.conf
Он удалит часть //
и любые пробелы до фактического текст, каким бы ни был этот текст.
Если вам понравился результат, вы можете добавить флаг -i
снова, чтобы заменить файл.
Чтобы рассказать больше о вашей попытке и объяснить, почему мой пример работает:
sed -i `s#^//[ \t]test#test#g'
'
) должна была использоваться здесь, вероятно. #
) - ваш выбранный разделитель, хорошая альтернатива общему прямому слешу (/
), так как ваш матч примерно такой же символ, и это исключает необходимость в экранировании. Шаблон в команде s/regexp/replacement/
является стандартным, как упомянуто в man-странице, среди многих других: man 1 sed
:
s/regexp/replacement/
Попытайтесь сопоставить регулярное выражение с пространством шаблона. В случае успеха замените ту часть, которая соответствует замене. Замена может содержать специальный символ
blockquote>&
для обозначения той части пространства шаблонов, которая соответствует, и специальные экранированные символы\1
-\9
для ссылки на соответствующие совпадающие подвыражения в регулярном выражении.
rexexp
в вышеприведенном является общепринятым сокращением для регулярных выражений . ^//[ \t]test$
сопоставляет строки, начинающиеся (^
) с двух косых черт, после пробела или символ табуляции, затем точную последовательность test
и конец строки ( $
). g
предназначен для выполнения этой операции глобально, как объяснено здесь . Вы не должны использовать косую черту в качестве разделителя. Фактически, я рекомендую использовать другие разделители, такие как запятые или хэши, для удобства чтения.
-i
также ваш друг, но используйте его, только если вы точно знаете, что это правильно. В этом случае я бы сделал что-то вроде:
sed -r 's,^//[ \t]*(.+),\1,' file.conf | less
Я использую -r
здесь для расширенного регулярного выражения, поэтому мне не нужно избегать скобок. Кроме того, это позволяет мне использовать оператор «плюс», что означает «одно или несколько вхождений». Следующее выражение будет эквивалентно:
sed 's,^//[ \t]*\(..*\),\1,' file.conf | less
(одна точка соответствует хотя бы одному символу, за которым следует ноль или более любого символа)
После того, как я уверен, что замена верна ( наберите косую черту, за которой следуют ваши ключевые слова в less
для поиска), я закрываю меньше, набрав q
, и перехожу к предыдущей записи в истории, нажимая клавишу «Вверх». Затем я удаляю | less
и набираю -i
, чтобы продолжить замену:
sed -r 's,^//[ \t]*(.+),\1,' file.conf -i
Если вы хотите глубже понять sed, я могу порекомендовать вам прочитать информационную страницу sed, которая более расширено, чем страница руководства:
info sed