bash 转义sed表达式中变量中的字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17272968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Escaping characters in variables inside sed expression
提问by Atomiklan
So im having an issue where this portion of my script is not working. I'm not sure exactly whats going on, but I get the feeling its because I have not escaped certain characters inside the variables. I tried the following with no luck:
所以我有一个问题,我的脚本的这部分不起作用。我不确定到底发生了什么,但我有这样的感觉,因为我没有在变量中转义某些字符。我尝试了以下但没有运气:
crontab -l | sed "s%$CTMP%\*\/$FREQ \* \* \* \* cd $DIR && \.\/$SCRIPT%" | crontab -
Here is whats in each of the variables:
这是每个变量中的内容:
The CTMP variable is just a line from the crontab file
CTMP 变量只是 crontab 文件中的一行
CTMP='*/5 * * * * cd /home/admin/whatever && ./test.sh'
The FREQvariable is the time in minutes setting of the cron file
该FREQ变量是 cron 文件设置的时间(以分钟为单位)
FREQ=5
The DIR variable is the current working directory
DIR 变量是当前工作目录
DIR='/home/admin/whatever'
And the SCRIPT variable is just the script file name
而 SCRIPT 变量只是脚本文件名
SCRIPT='test.sh'
I feel like the issue is the sed statement is not updating the crontab file because it's not escaping the characters it needs to inside these variables above.
我觉得问题是 sed 语句没有更新 crontab 文件,因为它没有将它需要的字符转义到上面的这些变量中。
Is that correct or is something else wrong?
这是正确的还是其他错误?
* UPDATE *
* 更新 *
CTMPESC=$(sed 's/[\*\.]/\&/g' <<<"$CTMP")
DIRESC=$(sed 's/[\*\.]/\&/g' <<<"$DIR")
SCRIPTESC=$(sed 's/[\*\.]/\&/g' <<<"$SCRIPT")
crontab -l | sed "s%$CTMPESC%\*/$FREQ \* \* \* \* cd $DIRESC && \./$SCRIPTESC%" | crontab -
* UPDATE *
* 更新 *
Here is the crontab output
这是 crontab 输出
*/10 * * * * cd /home/administrator/anm-1.5.0 */7 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh*/7 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh ./anm.sh
and I also echoed the three escaped variables just to troubleshoot and here they are:
我还回应了三个转义变量只是为了排除故障,它们是:
\*/7 \* \* \* \* cd /home/administrator/anm-1\.5\.0 && \./anm\.sh
/home/administrator/anm-1\.5\.0
anm\.sh
The three escaped variables actually look good.
三个转义变量实际上看起来不错。
* UPDATE *
* 更新 *
Cron file before the replace:
替换前的 Cron 文件:
*/10 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh
Cron file after the replace:
替换后的 Cron 文件:
*/7 * * * * cd /home/administrator/anm-1.5.0 */10 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh*/10 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh ./anm.sh
See all the extra junk that gets thrown in there somehow?
看到所有以某种方式被扔进那里的额外垃圾吗?
回答by Lev Levitsky
Yes, the problem is likely that $CTMPcontains asterisks, which are interpreted by sedas quantifiers. .is also a special character. Try escaping them:
是的,问题很可能$CTMP包含星号,这些星号被解释sed为量词。.也是一个特殊的人物。尝试逃避他们:
CTMP_ESC=$(sed 's/[\*\.]/\&/g' <<<"$CTMP")
and then use CTMP_ESCinstead of CTMP.
然后使用CTMP_ESC代替CTMP。
Also, you don't need to escape /in your sedcommand, because you are not using it as the s///separator.
此外,您不需要/在sed命令中转义,因为您没有使用它作为s///分隔符。
Edit:you also need to escape &in the replacement, because sedinterprets &as "the matched string". So your script should read:
编辑:您还需要&在替换中转义,因为sed解释&为“匹配的字符串”。所以你的脚本应该是:
CTMPESC=$(sed 's/[\*\.&]/\&/g' <<<"$CTMP")
DIRESC=$(sed 's/[\*\.&]/\&/g' <<<"$DIR")
SCRIPTESC=$(sed 's/[\*\.&]/\&/g' <<<"$SCRIPT")
crontab -l | sed "s%$CTMPESC%\*/$FREQ \* \* \* \* cd $DIRESC \&\& \./$SCRIPTESC%" | crontab -

