Подстановка sed переменными bash
Пытаясь изменить значения в текстовом файле, используя sed в bash-скрипте со строкой,
sed 's/draw($prev_number;n_)/draw($number;n_)/g' file.txt > tmp
Это будет в цикле. Не уверен, почему это не работает. Какие-либо предложения?
6 ответов
Переменные внутри '
не подставляйся в bash. Чтобы получить подстановку строк (или интерполяцию, если вы знакомы с Perl), вам нужно изменить его, чтобы использовать двойные кавычки "
вместо одинарных кавычек:
$ # enclose entire expression in double quotes
$ sed "s/draw($prev_number;n_)/draw($number;n_)/g" file.txt > tmp
$ # or, concatenate strings with only variables inside double quotes
$ # this would restrict expansion to relevant portion
$ # and prevent accidental expansion for !, backticks, etc
$ sed 's/draw('"$prev_number"';n_)/draw('"$number"';n_)/g' file.txt > tmp
$ # variable cannot contain arbitrary characters
$ # see link in further reading section for details
$ a='foo
bar'
$ echo 'baz' | sed 's/baz/'"$a"'/g'
sed: -e expression #1, char 9: unterminated `s' command
Дальнейшее чтение:
- Разница между одинарными и двойными кавычками в Bash
- Возможно ли избежать метасимволов регулярных выражений с помощью sed?
- Использование разных разделителей для команды sed substitute
- Если вам не нужен другой файл, вы можете использовать флаг -i, чтобы изменить файл на месте
Переменные в одинарных кавычках не раскрываются, в двойных кавычках в этом случае используются двойные кавычки.
sed "s/draw($prev_number;n_)/draw($number;n_)/g" file.txt > tmp
Вы также можете заставить его работать с eval
, но не делай этого!!
sed "s/draw($prev_number;n_)/draw($number;n_)/g"
это будет работать?
Вы можете использовать переменные, как показано ниже. Как здесь, я хотел заменить hostname
т.е. системная переменная в файле. Я ищу строку look.me
и заменить всю эту строку look.me=<system_name>
sed -i "s/.*look.me.*/look.me=`hostname`/"
Вы также можете сохранить системное значение в другой переменной и использовать эту переменную для подстановки.
host_var=
`hostname`
sed -i "s/.*look.me.*/look.me=$host_var/"
Входной файл:
look.me=demonic
Вывод файла (при условии, что мое системное имя prod-cfm-frontend-1-usa-central-1
):
look.me=prod-cfm-frontend-1-usa-central-1
Другой вариант с использованием:
SED_EXPR="$(printf -- 's/draw(%s;n_)/draw(%s;n_)/g' $prev_number $number)"
sed "${SED_EXPR}" file.txt
или в одну строку:
sed "$(printf -- 's/draw(%s;n_)/draw(%s;n_)/g' $prev_number $number)" file.txt
С использованиемprintf
чтобы построить выражение замены, должно быть безопасно от всевозможных странных вещей, поэтому мне нравится этот вариант.
I needed to input github tags from my release within github actions. So that on release it will automatically package up and push code to artifactory.
Here is how I did it. :)
- name: Invoke build
run: |
# Gets the Tag number from the release
TAGNUMBER=$(echo $GITHUB_REF | cut -d / -f 3)
# Setups a string to be used by sed
FINDANDREPLACE='s/${GITHUBACTIONSTAG}/'$(echo $TAGNUMBER)/
# Updates the setup.cfg file within version number
sed -i $FINDANDREPLACE setup.cfg
# Installs prerequisites and pushes
pip install -r requirements-dev.txt
invoke build
Retrospectively I wish I did this in python with tests. However it was fun todo some bash.