Из каких символов я должен выйти при использовании sed в sh сценарии?

Откройте/etc/mdadm/mdadm.conf файл, найдите строку, которая начинается ARRAY /dev/md1 и удалите строку сразу после который состояния 'spares=1'. Затем перезапустите mdadm сервис.

Если Вы сделали a mdadm --examine --scan для получения определений массива, в то время как массив md1 все еще восстанавливал один раздел рассматривался как запчасть в тот момент.

259
29.02.2012, 01:55
4 ответа

Существует два уровня интерпретации здесь: оболочка и sed.

В оболочке все между одинарными кавычками интерпретируется буквально, за исключением самих одинарных кавычек. У Вас может эффективно быть одинарная кавычка между одинарными кавычками путем записи '\'' (закройте одинарную кавычку, одну литеральную одинарную кавычку, открытую одинарную кавычку).

Sed использует основные регулярные выражения. В BRE, чтобы рассматривать их буквально, символы $.*[\^ потребность, которая будет заключена в кавычки путем предшествования им обратной косой чертой, кроме внутренних наборов символов ([…]). Буквы, цифры и (){}+?| не должен быть заключен в кавычки (можно сойти с рук заключение в кавычки некоторых из них в некоторых реализациях). Последовательности \(, \), \n, и в некоторых реализациях \{, \}, \+, \?, \| и другие backslash+alphanumerics имеют особые значения. Можно сойти с рук не заключение в кавычки $^ в некоторых положениях в некоторых реализациях.

Кроме того, Вам нужна обратная косая черта прежде / если это должно появиться в regex за пределами выражений скобки. Можно выбрать альтернативный символ в качестве разделителя путем записи, например, s~/dir~/replacement~ или \~/dir~p; Вам будет нужна обратная косая черта перед разделителем, если Вы захотите включать его в BRE. При выборе символа, который имеет особое значение в BRE, и Вы хотите включать его буквально, Вам будут нужны три обратных косых черты; я не рекомендую это, поскольку это может вести себя по-другому в некоторых реализациях.

Короче говоря для sed 's/…/…/':

  • Запишите regex между одинарными кавычками.
  • Использовать '\'' заканчиваться с одинарной кавычкой в regex.
  • Поместите обратную косую черту прежде $.*/[\]^ и только те символы (но не в выражениях скобки). (Технически Вы не должны помещать обратную косую черту прежде ] но я не знаю о реализации, которая рассматривает ] и \] по-другому за пределами выражений скобки.)
  • В выражении скобки, для - чтобы рассматриваться буквально, удостоверьтесь, что это является первым или последним ([abc-] или [-abc], нет [a-bc]).
  • В выражении скобки, для ^ чтобы рассматриваться буквально, удостоверьтесь, что это не является первым (использование [abc^], нет [^abc]).
  • Включать ] в списке символов, подобранных выражением скобки, сделайте это первым символом (или сначала после ^ для отрицаемого набора): []abc] или [^]abc] (нет [abc]] ни [abc\]]).

В тексте замены:

  • & и \ потребность, которая будет заключена в кавычки путем предшествования им обратной косой чертой, также, как и разделитель (обычно /) и новые строки.
  • \ сопровождаемый цифрой имеет особое значение. \ сопровождаемый буквой имеет особое значение (специальные символы) в некоторых реализациях, и \ сопровождаемый некоторыми другими символьными средствами \c или c в зависимости от реализации.
  • С одинарными кавычками вокруг аргумента (sed 's/…/…/'), используйте '\'' помещать одинарную кавычку в текст замены.

Если regex или текст замены прибывают из переменной оболочки, помните это

  • regex является BRE, не литеральной строкой.
  • В regex новая строка должна быть выражена как \n (который никогда не будет соответствовать, если у Вас не будет другого sed код, добавляющий символы новой строки к пространству шаблона). Но обратите внимание, что это не будет работать в выражениях скобки с некоторыми sed реализации.
  • В тексте замены, &, \ и новые строки должны быть заключены в кавычки.
  • Разделитель должен быть заключен в кавычки (но не в выражениях скобки).
  • Используйте двойные кавычки для интерполяции: sed -e "s/$BRE/$REPL/".
296
27.01.2020, 19:27

Проблема, которую Вы испытываете, не должна окружить интерполяцию и Escape - это - потому что Вы пытаетесь использовать синтаксис расширенного регулярного выражения, не передавая sed -r или --regexp-extended опция.

Измените свою sed строку от

sed 's/(127\.0\.1\.1)\s/\1/' [some file]

кому:

sed -r 's/(127\.0\.1\.1)\s/\1/' [some file]

и это будет работать, поскольку я полагаю, что Вы предназначаете.

По умолчанию использование sed использует основные регулярные выражения (думайте стиль grep), который потребовал бы следующего синтаксиса:

sed 's/\(127\.0\.1\.1\)[ \t]/\1/' [some file]
45
27.01.2020, 19:27
  • 1
    я имел эту проблему снова и забыл прокручивать вниз для нахождения решения мной в upvoted прошлый раз. Еще раз спасибо. –  isaaclw 04.04.2014, 23:17
  • 2
    Большое спасибо. Добавление -r поскольку опция была тем, что было необходимо в моем случае. –  HelloGoodbye 21.05.2015, 11:23

Если Вы не хотите интерполировать переменную оболочки в sed выражение, используйте одинарные кавычки для целого выражения, потому что они заставляют все между ними интерпретироваться как есть, включая обратные косые черты.

Таким образом, если Вы хотите, чтобы sed видел s/\(127\.0\.1\.1\)\s/\1/ поместите одинарные кавычки вокруг этого, и оболочка не коснется круглых скобок или обратных косых черт в нем. Если необходимо интерполировать переменную оболочки, поместите только ту часть в двойные кавычки. Например.

sed 's/\(127\.0\.1\.1\)/'"$ip"'/'

Это избавит Вас от необходимости помнить, каких метасимволов оболочки не оставляют двойные кавычки.

17
27.01.2020, 19:27
  • 1
    , который я хочу sed видеть s/(127\.0\.1\.1)/..., но помещение этого в сценарии оболочки как есть не работает. То, что Вы говорите об оболочке, не касающейся круглых скобок, кажется неправильным. Я отредактировал свой вопрос уточнить. –  detly 28.02.2012, 08:14
  • 2
    Оболочка не касается круглых скобок. Вам нужен backslases, потому что sed должен видеть их. sed 's/(127\.0\.1\.1)/IP \1/' сбои, потому что sed должен видеть \( и \) для синтаксиса группы, нет ( и ). фейспалм –  Kyle Jones 28.02.2012, 08:31
  • 3
    Это не находится в странице справочника, но это НАХОДИТСЯ в некотором руководстве онлайн, которое я нашел. Действительно ли это нормально для regex, потому что я никогда не должен был использовать его в regex библиотеках (в, например, Python)? –  detly 28.02.2012, 08:33
  • 4
    Для традиционных команд Unix существуют основные регулярные выражения и расширенные регулярные выражения.Подробнее. sed использует основные регулярные выражения, таким образом, обратные косые черты необходимы для синтаксиса группы. Perl и Python пошли даже вне расширенных регулярных выражений. В то время как я вводил по абсолютному адресу вокруг, я нашел чрезвычайно информативную диаграмму, которая иллюстрирует то, что запутывающую ежевику мы вызываем в воображении, когда мы многословно говорим "регулярное выражение". –  Kyle Jones 28.02.2012, 09:07
  • 5
    я также добавил бы, что единственный символ, который не может использоваться в одинарных кавычках, является одинарной кавычкой. –  enzotib 28.02.2012, 11:08

Я думаю, стоит упомянуть, что, хотя sed основан на стандарте POSIX, который определяет поддержку только базовых регулярных выражений (BRE ), на самом деле существуют две разные версии команды sed -BSD (Mac OS )и дистрибутивы GNU (Linux ). Каждая версия реализует как аналогичные, так и уникальные расширения стандарта POSIX и может влиять на функциональность sed на разных платформах. В результате правильный синтаксис команды sed, работающий должным образом в одной системе, может привести к совершенно другим результатам в другой. Это может привести к неожиданному поведению в отношении использования экранированных и специальных символов.

Эти расширения стандарта POSIX, как правило, более распространены в версии GNU sed, часто обеспечивая удобство менее строгого форматирования, особенно по сравнению с версией BSD. Однако, хотя GNU sed позволяет использовать некоторые специальные символы, на самом деле они все еще не совместимы с POSIX -. Кроме того, единственная реальная разница между базовым и расширенным регулярным выражением (ERE )в GNU sed заключается в поведении следующих специальных символов:

«?», «+», скобки, фигурные скобки («{}» )и «|»

Хотя это может иметь место, некоторые специальные символы имеют ограниченную поддержку или вообще не поддерживаются в BSD sed, например «|», «?» и «+», поскольку они более точно соответствуют стандартам синтаксиса POSIX. Включение этих символов аналогично GNU sed часто приводит к проблемам с переносимостью и функциональностью скриптов, использующих sed. Также стоит отметить, что синтаксис POSIX BRE не определяет значение некоторых escape-последовательностей, в первую очередь :\|, +, \?, `, \', \<, >, \b, \B, \ w, и \W,.

Для тех, кто использует версию sed для BSD/Mac OS, эмулировать поведение некоторых специальных символов может быть немного сложно, но в большинстве случаев это можно сделать. Например, + можно эмулировать в соответствии с POSIX -следующим образом :{1,} и \? будет выглядеть так :{0,1} Однако последовательности управляющих символов обычно не поддерживаются. Если это вообще возможно, конечно, проще всего использовать GNU sed, но если вам нужна функциональность на обеих платформах, не забудьте использовать только функции POSIX, чтобы обеспечить переносимость. Если вы пользователь Mac и хотели бы воспользоваться преимуществами GNU sed, а не BSD sed, вы можете попробовать установить Homebrew и загрузить GNU sed через командную строку с помощью :$brew install gnu -sed.

Подводя итог, отметим, что различия в версиях действительно могут определять, как может выглядеть правильный синтаксис.или какие символы необходимы для побега. Я надеюсь, что это дает некоторый дополнительный контекст для первоначального вопроса, а также принятый ответ, и помогает другим подумать, как им следует действовать, исходя из конечной цели их сценария и использования команды.

3
20.08.2021, 13:28

Теги

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