Backsla sh путаница с использованием bash / sed для замены имени пользователя переменной именем переменной? - PullRequest
0 голосов
/ 18 февраля 2020

Используя Bash, следующая подстановка sed заменяет имя пользователя во входной строке на %USERNAME (это переменная DOS):

echo "c:\\cygwin64\\home\\$USERNAME\SomeFolder" \
   | sed -e "s=\\$USERNAME\>=\\%USERNAME%="

Следующее не может сделать то же самое :

echo "c:\\cygwin64\\home\\$USERNAME\SomeFolder" \
   | sed -e "s=home\\$USERNAME\>=home\\%USERNAME%="

Контекст

Это входит в bash функцию

cpawusr () { cygpath -aw "$@" | sed -e "s=\\home\\$USERNAME\>=\\home\\%USERNAME%=g" ; }

Эта функция будет использоваться разными пользователями, и я хочу, чтобы $ USERNAME раскрывался при вызове функции, поэтому в двойных кавычках.

1 Ответ

1 голос
/ 18 февраля 2020

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

echo "c:\\cygwin64\\home\\$USERNAME\SomeFolder" |
    sed -e "s=home\\\\$USERNAME\>=home\\\\%USERNAME%="

Другое решение заключается в использовании одинарных кавычек, где это возможно:

echo "c:\\cygwin64\\home\\$USERNAME\SomeFolder" |
    sed -e 's=home\\'"$USERNAME"'\>=home\\%USERNAME%='

В Исходный код с двойными кавычками, оболочка анализирует строку и заменяет каждую пару \\ одной \. Затем sed видит одну обратную бэкслу sh и использует ее для экранирования следующего символа. При использовании четырехкратных обратных косых черт sed видит \\ и обрабатывает это как \, как и предполагалось.

В сценарии с одинарными кавычками оболочка не интерпретирует данные в одинарных кавычках, но он расширяется $USERNAME в двойных кавычках.

Замечу, что для записи \> требуется GNU sed; BSD (macOS) sed не распознает его, даже с -E для расширенных регулярных выражений.

...