Intereting Posts

Какие символы мне нужно избегать при использовании sed в сценарии sh?

Возьмите следующий скрипт:

#!/bin/sh sed 's/(127\.0\.1\.1)\s/\1/' [some file] 

Если я попытаюсь запустить это в sh ( dash здесь), он будет терпеть неудачу из-за круглых скобок, которые необходимо экранировать. Но мне не нужно избегать обратных косых черт (между октетами или в \s или \1 ). Какое правило здесь? Как насчет того, когда мне нужно использовать {...} или [...] ? Есть ли список того, что я делаю, и мне не нужно бежать?

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

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

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

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

В двух словах, для sed 's/…/…/' :

  • Напишите регулярное выражение между одинарными кавычками.
  • Используйте '\'' чтобы получить одну цитату в регулярном выражении.
  • Положите обратную косую черту перед $.*/[\]^ И только те символы.

В заменяющем тексте:

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

Если регулярное выражение или текст замены поступают из переменной оболочки, помните, что

  • регулярное выражение – это BRE, а не буквальная строка;
  • в регулярном выражении новая строка должна быть выражена как \n ;
  • в заменяющем тексте & , \ и новые строки должны быть указаны;
  • разделитель должен быть указан.
  • Используйте двойные кавычки для интерполяции: sed -e "s/$BRE/$REPL/"

Проблема, с которой вы столкнулись, происходит не из-за интерполяции и экранирования оболочки – это потому, что вы пытаетесь использовать расширенный синтаксис регулярных выражений, не передавая параметр -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] 

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

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

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

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