LINUX.ORG.RU

Знак доллара и sed

 , ,


0

1

Если запускать echo | sed внутри обратных апострофов, знак доллара не заменит. Если вне их, заменит:

$ name1='a$b'; echo $name1 | sed 's/\$/ /g'; name2=`echo $name1 | sed 's/\$/ /g'`; echo $name2
a b
a$b

Если заменить $ на \x24, то не сработает нигде:

$ name1='a$b'; echo $name1 | sed 's/\x24/ /g'; name2=`echo $name1 | sed 's/\x24/ /g'`; echo $name2
a$b 
a$b

Но если взять \x24 в квадратные скобки, заработает:

$ name1='a$b'; echo $name1 | sed 's/[\x24]/ /g'; name2=`echo $name1 | sed 's/[\x24]/ /g'`; echo $name2
a b
a b

Почему так происходит?

★★★★★

По первой части вопроса, man bash, Command Substitution.

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $, `, or \.

По поводу квадратный скобок у sed:

GNU sed processes escape sequences before passing the text onto the regular-expression matching of the s/// command and Address matching.

То есть ″/\x24/″ для sed обозначает конец строки.

mky ★★★★★ ()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от mky

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $, `, or .

Вот эту фразу я не понимаю.

Что значит «old-style backquote»? С `?

Что значит «retains its literal meaning»? Не считается спецсимволом? Но тут же идёт оговорка «except when followed by $» — именно мой случай.

То есть для комбинации \$ обратная косая черта является спецсимволом и экранирует доллар? Этого не происходит.

Но с $( ... ) всё работает как я и хочу:

name1='a$b'; echo $name1 | sed 's/\$/ /g'; name2=$(echo "$name1" | sed 's/\$/ /g'); echo "$name2"
a b
a b

GNU sed processes escape sequences before passing the text onto the regular-expression matching of the s/// command and Address matching.

То есть ″/\x24/″ для sed обозначает конец строки.

То есть \x24 преобразуется в неэкранированный доллар, который считается спецсимволом, и чтобы его заэкранировать, нужно добавить \ в таком же виде: \x5c.

$ name1='a$b'; echo $name1 | sed 's/\x5c\x24/ /g'; name2=`echo "$name1" | sed 's/\x5c\x24/ /g'`; echo "$name2"
a b
a b

Спасибо.

question4 ★★★★★ ()
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4
$ name1='a$b'; echo "'$name1'" | sed 's/\$/ /g'; name2=`echo $name1 | sed 's/\$/ /g'`; echo "'$name2'"
'a b'
'a$b '

`` превращает \$ в $, т.е. в признак конца строки, т.к. по документации \$, \` и \\ являются сцециальными последовательностями. Если удвоить, тогда sed увидит \$ и всё будет работать как ожидалось.

Что значит «retains its literal meaning»?

Что он на что не заменяется.

xaizek ★★★★★ ()
Ответ на: комментарий от question4

Что значит «old-style backquote»?

$(command) — это новый способ, а обратные кавычки $`command` — это старый способ подстановки команды. Это не башизм, оба есть в POSIX, но во времена SystemV были только обратные кавычки.

На остальные вопросы, вроде ответили, но вот более короткий пример, без sed:

echo '\$' ; echo `echo '\$'`

mky ★★★★★ ()
Ответ на: комментарий от mky

вот более короткий пример, без sed

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

question4 ★★★★★ ()
Ответ на: комментарий от mky

(command) — это новый способ, а обратные кавычки $`command` — это старый способ подстановки команды.

Ну все же старый синтаксис без $ в начале.

но во времена SystemV были только обратные кавычки.

Да, так как тогда люди подходили к синтаксису строже. Сейчас же, вложенные кавычки — тут нельзя, тут можно, там надо, тут без отдельной опции не работает, или работает по разному в разных версиях типа $'C-ctyle' внутри Parameter Expansion.

vodz ★★★★★ ()