2017-01-11 3 views
1

Моя цель - заменить все «специальные» строки из текстового файла и заменить их системными переменными. Например, как вход будет линия, как это:Замените часть строки расширением переменной оболочки

__HOME__/properties/common/file.properties 

Здесь специальная строка __HOME__ и я должен заменить его HOME системной переменной $. Как выход он должен быть:

/home/user/properties/common/file.properties 

Я пытался решить эту проблему с sed командой, и я пришел к этой точке:

echo __HOME__/properties/common/file.properties | sed -e 's/\(__\)\([A-Z]*\)\(__\)/\2/g' 

Как выход я получаю HOME/properties/common/file.properties что неправильно. Я пытался заменить обратную ссылку от sed (здесь \2) с чем-то вроде echo \2, но это не сработает. Есть ли что-нибудь, что можно сделать в Баше?

+1

Я правильно понимаю, что вы хотите написать общий код, который может заменить любую переменную? Я не уверен, сможет ли это сделать. Его можно запрограммировать в Bash с некоторыми усилиями и, вероятно, намного чище на более мощном языке, таком как Python. По соображениям безопасности я бы рекомендовал вам явно перечислять переменные, которые могут быть расширены в любом случае. – 5gon12eder

ответ

3

Может использовать Perl

perl -lpe 's/__(.+?)__/$ENV{$1}/g' file 

Просто проверяет строки, которые имеют __something__ и заменяют их с переменным окружением из вашей оболочки.

+1

Это именно то, что я ищу, спасибо! – Tom

2

Вы можете использовать eval для этого:

s='__HOME__/properties/common/file.properties' 
eval "printf '%s\n' "$(sed 's/__\([A-Za-z_][a-zA-Z0-9_]*\)__/$\1/g' <<< "$s")"" 

/home/user111/properties/common/file.properties 
+1

Это также хороший ответ, спасибо! – Tom

1

Может использовать Python

# coding=utf8 
# the above tag defines encoding for this document and is for Python 2.x compatibility 

import re 

regex = r"(\_.*\_)" 

test_str = "__HOME__/properties/common/file.properties" 

subst = "/home/potato" 

# You can manually specify the number of replacements by changing the 4th argument 
result = re.sub(regex, subst, test_str, 0, re.MULTILINE) 

if result: 
    print (result) 

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution. 

Результат:

/home/potato/properties/common/file.properties 
2

Мы можем еще больше упростить этот процесс, USI нг другой разделитель для sed выражения - я использовал # вместо /:

path='__HOME__/properties/common/file.properties' 
sed "s#__HOME__#$HOME#" <<< "$path" 
# output => /Users/codeforester/properties/common/file.properties 

Поскольку выражение sed заворачивают в двойных кавычках, это делает расширение $HOME и хлещет в $HOME расширения не нарушило бы выражение sed потому что мы используем # в качестве разделителя. Любой символ может быть выбран в качестве разделителя, если он не встречается ни в одной другой части выражения.

+1

Это, безусловно, самый читаемый вариант для меня. – thun

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