Использование значения внутри переменной без расширения - PullRequest
0 голосов
/ 29 апреля 2019

Я пытаюсь найти и заменить определенное текстовое содержимое с помощью команды sed и запустить его с помощью сценария оболочки.

Ниже приведен пример сценария, который я использую:

fp=/asd/filename.txt

fd="sed -i -E 's ($2).* $2:$3 g' ${fp}"
eval $fd

и выполнить то же самое, передав аргументы:

./test.sh update asd asdfgh

Но если строка аргумента содержит $, она прерывает команды и заменяет неправильные значения, такие как

./test.sh update asd $apr1$HnIF6bOt$9m3NzAwr.aG1Yp.t.bpIS1.

Как я могу убедиться, что значения внутри переменных не раскрыты из-за $?

Обновлено

sh file test.sh

set -xv

fp="/asd/filename.txt"

sed -iE "s/(${2//'$'/'\$'}).*/${2//'$'/'\$'}:${3//'$'/'\$'}/g" "$fp"

текстовый файл filename.txt

hello:world

Выходы

1) ./test.sh update hello WORLD

sed -iE "s/(${2//'$'/'\$'}).*/${2//'$'/'\$'}:${3//'$'/'\$'}/g" "$fp"
++ sed -iE 's/(hello).*/hello:WORLD/g' /asd/filename.txt

2) ./test.sh update hello '$ apr1 $ hosgaxyv $ D0KXp5dCyZ2BUYCS9BmHu1 '

sed -iE "s/(${2//'$'/'\$'}).*/${2//'$'/'\$'}:${3//'$'/'\$'}/g" "$fp"
++ sed -iE 's/(hello).*/hello:'\''$'\''apr1'\''$'\''hosgaxyv'\''$'\''D0KXp5dCyZ2BUYCS9BmHu1/g' /asd/filename.txt

В обоих случаях его содержимое не заменяется

Ответы [ 3 ]

2 голосов
/ 29 апреля 2019

Вам вообще не нужно eval здесь:

fp=/asd/filename.txt
sed -i -E "s/(${2//'$'/'\$'}).*/\1:${3//'$'/'\$'}/g" "$fp"
  • Вся команда sed заключена в двойные кавычки, поэтому переменные могут расширяться.
  • Я заменилпробел в качестве разделителя s с / (в данном случае это не имеет значения).
  • Я использовал \1 для ссылки на первую группу захвата вместо повторения переменной в подстановке.
  • Самое главное, я использовал ${2//'$'/'\$'} вместо $2 (и аналогично для $3).Это экранирует каждый знак $ как \$;это требуется из-за двойных кавычек или из-за того, что оболочка съедает $ до того, как sed увидит их.

Когда вы вызываете свой скрипт, вы должны экранировать любые $ вили оболочка пытается раскрыть их как имена переменных:

./test.sh update asd '$apr1$HnIF6bOt$9m3NzAwr.aG1Yp.t.bpIS1.'
0 голосов
/ 01 мая 2019

должен защищать все аргументы скрипта с кавычками, если у них есть пробел и специальный символ оболочки, и избегать его, если это доллар $, а -Ei вместо -iE, даже лучше, сначала отбросить его для теста, может добавить его позжеесли я действительно уверен,
Я признаю, что не буду разбираться в вашем регулярном выражении, так что давайте просто погрузимся в суть решения, не нужно eval;

fp=/asd/filename.txt

sed -Ei "s/($2).*/$2:$3/g" $fp

./test.sh update asd '\$apr1\$HnIF6bOt\$9m3NzAwr.aG1Yp.t.bpIS1.'
0 голосов
/ 29 апреля 2019

Поместите аргументы командной строки, которые являются именами файлов, в одинарные кавычки:

./test.sh update 'asd' '$apr1$HnIF6bOt$9m3NzAwr.aG1Yp.t.bpIS1'
...