Возьмите следующий скрипт:
#!/bin/sh
sed 's/(127\.0\.1\.1)\s/\1/' [some file]
Если я попытаюсь запустить это в sh
( dash
здесь), это потерпит неудачу из-за круглых скобок, которые должны быть экранированы. Но мне не нужно избегать обратной косой черты (между октетами или в \s
или \1
). Какое правило здесь? Как насчет того, когда мне нужно использовать {...}
или [...]
? Есть ли список того, что я делаю и не нужно убегать?
shell-script
sed
quoting
detly
источник
источник
function sedPath { path=$((echo $1|sed -r 's/([\$\.\*\/\[\\^])/\\\1/g'|sed 's/[]]/\[]]/g')>&1) } #Escape path for use with sed
Ответы:
Здесь есть два уровня интерпретации: shell и sed.
В оболочке все между одинарными кавычками интерпретируется буквально, за исключением самих одинарных кавычек. Вы можете эффективно заключить одинарную кавычку в одинарные кавычки
'\''
(закрыть одинарную кавычку, одну буквальную одинарную кавычку, открыть одинарную кавычку).Sed использует основные регулярные выражения . В BRE, чтобы их можно было трактовать буквально, символы
$.*[\^
должны быть заключены в кавычки, перед ними стоит обратная косая черта, за исключением внутренних наборов символов ([…]
). Буквы, цифры и(){}+?|
не должны быть заключены в кавычки (вы можете избежать цитирования некоторых из них в некоторых реализациях). Последовательности\(
,\)
,\n
, и в некоторых реализациях\{
,\}
,\+
,\?
,\|
и другой обратный слэш + буквенно - цифровые имеют особое значение. Вы можете избежать неприятностей$^
в некоторых позициях в некоторых реализациях.Кроме того, вам нужен обратный слеш перед тем
/
, как он появится в регулярном выражении вне выражений в скобках. Вы можете выбрать альтернативный символ в качестве разделителя, написав, например,s~/dir~/replacement~
или\~/dir~p
; перед разделителем вам понадобится обратный слеш, если вы хотите включить его в BRE. Если вы выбираете символ, имеющий особое значение в BRE, и хотите включить его буквально, вам понадобится три обратных слеша; Я не рекомендую это, поскольку это может вести себя по-другому в некоторых реализациях.В двух словах, для
sed 's/…/…/'
:'\''
чтобы закончить с одинарной кавычкой в регулярном выражении.$.*/[\]^
и только этими символами (но не внутри скобочных выражений). (Технически вы не должны ставить обратную косую черту раньше,]
но я не знаю реализации, которая обрабатывает]
и\]
отличается от скобочных выражений.)-
чтобы его можно было трактовать буквально, убедитесь, что оно первое или последнее ([abc-]
или[-abc]
нет).[a-bc]
^
чтобы его можно было трактовать буквально, убедитесь, что оно не первое (используйте[abc^]
, а не).[^abc]
]
в список символов, совпадающих с выражением в скобках, сделайте его первым символом (или первым после^
для отрицательного набора):[]abc]
или[^]abc]
(не).[abc]]
ни[abc\]]
В тексте замены:
&
и\
должны быть заключены в кавычки, перед ними стоит обратная косая черта, как и разделитель (обычно/
) и символы новой строки.\
сопровождаемая цифра имеет особое значение.\
сопровождаемая буквой имеет специальное значение (специальные символы) в некоторых реализациях, и\
после нее следуют некоторые другие символьные средства\c
или вc
зависимости от реализации.sed 's/…/…/'
), используйте,'\''
чтобы поместить одинарную кавычку в текст замены.Если регулярное выражение или текст замены происходит из переменной оболочки, помните, что
\n
(который никогда не будет совпадать, если у вас нет другогоsed
кода, добавляющего символы новой строки в пространство шаблона). Но обратите внимание, что он не будет работать внутри скобочных выражений с некоторымиsed
реализациями.&
,\
и новые строки должны быть в кавычках.sed -e "s/$BRE/$REPL/"
.источник
\\*
). Пример:echo "***NEW***" | sed /\\*\\*\\*NEW\\*\\*\\*/s/^/#/
Проблема, с которой вы столкнулись, заключается не в интерполяции и экранировании оболочки, а в том, что вы пытаетесь использовать расширенный синтаксис регулярного выражения, не передавая параметр sed
-r
или or--regexp-extended
.Измените свою линию sed с
в
и это будет работать, как я полагаю, вы собираетесь.
По умолчанию sed использует базовые регулярные выражения (думаю, стиль grep), для которых требуется следующий синтаксис:
источник
-r
в качестве опции было то, что было необходимо в моем случае.Если вы не хотите интерполировать переменную оболочки в выражение sed, используйте одинарные кавычки для всего выражения, поскольку они приводят к тому, что все между ними интерпретируется как есть, включая обратную косую черту.
Так что если вы хотите , чтобы увидеть СЕПГ
s/\(127\.0\.1\.1\)\s/\1/
ставить одиночные кавычки вокруг него и оболочка не будет касаться скобок или слэш в нем. Если вам нужно интерполировать переменную оболочки, поместите только эту часть в двойные кавычки. НапримерЭто избавит вас от необходимости запоминать, какие метасимволы оболочки не экранируются двойными кавычками.
источник
sed
видетьs/(127\.0\.1\.1)/...
, но поместить это в сценарий оболочки как есть, не работает. То, что вы говорите о оболочке, не касающейся скобок, кажется неправильным. Я отредактировал свой вопрос, чтобы уточнить.sed 's/(127\.0\.1\.1)/IP \1/'
не удается, потому что sed нужно видеть\(
и\)
для группового синтаксиса, а не(
и)
.