我有一个缩小的js文件。包含特殊字符,如管道,破折号,斜线等。
另外,我还有另一个包含评论的HTML文件:
<!--#MY_SNIPPET#-->
我正在尝试使用sed
来注入我的js文件并将其替换为上面的注释。
my.js
<script>whatever|@</script><script>-my</script>
我现在正在做:
VARIABLE=$(cat my.js)
sed -i "s|<!--#MY_SNIPPET#-->|${VARIABLE}|" index.html
但我得到了sed: unmatched '|'
我认为sed
正在尝试评估字符串,这就是失败的原因,但我想知道是否有一种简单的方法可以使用sed
,因为我想避免使用Perl
或其他任何内容。
分隔符无关紧要,它总是会抛出同样的错误。
答案 0 :(得分:1)
在某些情况下,构建动态sed表达式即使不是不可能也很困难。你的问题有两个:双引号里面(或外面)的感叹号!
有特殊用途,例如:在控制台上试试这些
!!
这个重复最后执行的命令(小心!:D)
echo "!$"
回显上一个命令的最后一个参数
!5087
在bash历史记录中执行命令5087。
另一个 big 问题是你的变量几乎可能包含任何字符,所以你不能确定那里没有sed表达式分隔符,对于你的特定例子,这是有效的
sed -ri "s~<[!]--#MY_SNIPPET#-->~${var}~" test.html
PS:分隔符必须是单字节字符:(
sed -ri "sЖ<[!]--#MY_SNIPPET#-->Ж${var}Ж" test.html
sed: -e expression #1, char 2: delimiter character is not a single-byte character
另一个扭曲的选项可能是在VARIABLE中替换所选的分隔符,然后将其恢复
sed -ri "s@<[!]--#MY_SNIPPET#-->@$(echo "${var}" | tr '@' 'ж')@" test.html
cat test.html | tr 'ж' '@' > test2.html
mv test2.html test.html
答案 1 :(得分:0)
永远不要将整个脚本用双引号括起来,然后将整个脚本暴露给shell进行解释,这可能会产生像你现在体验到的无法预料的后果。如果/当您需要shell执行特定任务时,仅将脚本打开到shell,例如在您的情况下扩展变量。用单引号括起脚本,而不是加倍。
所以,不要写:
sed -i "s|<!--#MY_SNIPPET#-->|${VARIABLE}|" index.html
改为写这个:
sed -i 's|<!--#MY_SNIPPET#-->|'"${VARIABLE}"'|' index.html
现在您的下一个问题是VARIABLE包含您在脚本|
中使用的分隔符。要解决此问题,只需更改脚本中的分隔符,例如从|
到~
:
sed -i 's~<!--#MY_SNIPPET#-->~'"${VARIABLE}"'~' file
那将&#34;工作&#34;只要VARIABLE不包含任何~
,&
或\<number>
字符/字符串。对于更强大的解决方案,您需要执行它在Is it possible to escape regex metacharacters reliably with sed上显示的内容或切换到awk,因为awk可以在文字字符串上操作,而sed则不能。
答案 2 :(得分:0)
无论您使用s///
命令的分隔符,您的变量可能包含该字符的风险。最好的做法是在变量中转义任何这样的字符:
$ var='<script>whatever|@</script><script>-my</script>'
$ echo "${var//|/\\|}"
<script>whatever\|@</script><script>-my</script>
# ..............^^
然后
sed -i "s|<!--#MY_SNIPPET#-->|${var//|/\\|}|" index.html