2013-12-20 3 views
0

Я пытаюсь реализовать sed replace с переменными оболочки. Насколько сейчас я рабочий СЭД заменить 'Sed заменить на переменные оболочки

sed -i -r 's#(export\ PATH=")(.*)#\1/home/USER/bin:~/.local/bin:\2#' ~/.zshrc 

' Но, к сожалению, не расширять переменные оболочки так же, как указано в этом ответе https://stackoverflow.com/a/5156322/675100

При попытке использовать " я получаю проблемы со скобками и т.д. Я хотел бы сделать это родовое всегда использовать whoami вместо USER

Первая попытка будет

sed -i -r "s#\(export\ PATH=\"\)(.*)#\1/home/`whoami`/bin:~/.local/bin:\2#" ~/.zshrc 
sed: -e expression #1, char 60: invalid reference \2 on `s' command's RHS 

EDIT

Я попытался

sed -i -r "s#\(export\ PATH=\"\)\(.*\)#\1/home/$(whoami)/bin:~/.local/bin:\2#" ~/.zshrc 

, чтобы избежать второй группы, но я получаю подобную ошибку:

sed: -e expression #1, char 63: invalid reference \2 on `s' command's RHS 
+0

Обратите внимания, что только' $ ' и back-ticks вызывают проблемы внутри двойных кавычек; круглые скобки применимы только в том случае, когда предшествует '$' как в '$ (whoami)' и т. д. –

+0

Вы избежали первой пары круглых скобок, но не вторую пару вокруг '(. *)'. Вот почему нет второй группы, на которую можно ссылаться с '\ 2'. Кроме того, что такое '-r'? Моя копия 'sed' не имеет этого ... – svckr

+0

Почему вы специально используете'/home/USER/bin' вместо '~/bin'? –

ответ

3

Вы можете написать так:

sed -i 's#export PATH="#&/home/'$(whoami)'/bin:~/.local/bin:#' ~/.zshrc 

Или, как @glennjackman отметил:

sed -i 's#export PATH="#&~/bin:~/.local/bin:#' ~/.zshrc 

Обратите внимание, что:

  • Вместо согласования (начало) (конец) и вставляя между похожими (start) «newstuff» (конец), вы можете сопоставить только (start), заменить его на себя, используя & и вставить свой «новый материал»
  • Чтобы упростить квотирование, вы можете закончить сингл цитируемой части в любое время и начать новый сингл цитируемой части позже, потому что они эквивалентны:

    echo 'hello there' 
    echo 'hello'' there' 
    
0

Ok поэтому проблема была с -r флагом который использовал расширенные регулярные выражения.

Окончательное решение было использовать:

sed -i "s#\(export\ PATH=\"\)\(.*\)#\1/home/$(whoami)/bin:~/\.local/bin:\2#" ~/.zshrc 
1

обратный слэш ускользает преформируются в двойные кавычки строки, так что вы должны бежать все обратные слэши!

sed -i -r "s#\\(export PATH=\"\\)\\(.*\\)#\\1/home/$(whoami)/bin:~/.local/bin:\\2#" ~/.zshrc 

Чтобы определить домашний каталог пользователя, воспользуйтесь одним из приведенных ниже параметров.

sed -i -r "s#\\(export PATH=\"\\)\\(.*\\)#\1~/bin:~/.local/bin:\\2#" ~/.zshrc 
sed -i -r "s#\\(export PATH=\"\\)\\(.*\\)#\1$HOME/bin:~/.local/bin:\\2#" ~/.zshrc 
sed -i -r "s#\\(export PATH=\"\\)\\(.*\\)#\1$(getent passwd $LOGNAME | cut -d: -f6)/bin:~/.local/bin:\\2#" ~/.zshrc 

Весь ваш подход выглядит хрупким.

  • Что делать, если PATH уже экспортирован, я использую PATH="..."?
  • Что делать, если я использую одинарные кавычки?
  • Что делать, если я использую другой файл точки?

Почему вы не просто использовать

PATH="~/bin:~/.local/bin:$PATH" 

??

Смежные вопросы