Unexpected substitution for & with sed

2019-07-18 07:24发布

I have a CSV file containing some special characters and their HTML entity names

ex: htm.csv

À,À
Á,Á
Â,Â
Ã,Ã
É,É
Ê,Ê
Í,Í
Ó,Ó
Ô,Ô
Õ,Õ

and I have a number of .php files where these special characters are present. I have written a shell script

#!/bin/bash
IFS=","
while read orig html
do
   for fl in *.php; do
   mv $fl $fl.old
   sed 's/'$orig'/'$html'/g' $fl.old > $fl
   done
done< "htm.csv"

but the problem is when using the contents of $html, it is printing the contents of $orig instead of "&".

3条回答
Deceive 欺骗
2楼-- · 2019-07-18 07:40

Use any character as a command delimiter, here is an example:

sed -Ei "s|$k|$j|g" filename.txt
查看更多
乱世女痞
3楼-- · 2019-07-18 07:53

In addition to the special characters you can also make the commands a bit safer and shorter:

  • There's no need for mv if your sed supports -i (in-place replacement)
  • To avoid setting IFS for the rest of the commands you can limit its scope
  • Escape & in $html

The result:

#!/bin/bash
while IFS="," read orig html
do
    for fl in *.php
    do
        sed -i 's/'$orig'/'${html//&/\\&}'/g' "$fl"
    done
done < "htm.csv"

Please add an example if it doesn't work for you. There could be other special characters which would have to be escaped.

查看更多
叼着烟拽天下
4楼-- · 2019-07-18 08:02

& is a special character meaning "the whole matched string" in the s/// command. Use \&.

查看更多
登录 后发表回答