【问题标题】:Unexpected substitution for & with sed用 sed 意外替换 &
【发布时间】:2011-09-06 05:07:58
【问题描述】:

我有一个 CSV 文件,其中包含一些特殊字符及其 HTML 实体名称

例如:htm.csv

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

我有许多.php 文件,其中存在这些特殊字符。我写了一个shell脚本

#!/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"

但问题是当使用$html 的内容时,它打印的是$orig 的内容而不是"&amp;"

【问题讨论】:

    标签: shell csv utf-8 sed


    【解决方案1】:

    &amp;s/// 命令中的一个特殊字符,意思是“整个匹配的字符串”。使用\&amp;

    【讨论】:

    • 使用 \\& 它的工作但对于一堆文件它不工作
    • 有关文档,请参阅here
    • "要在最终替换中包含文字 \、& 或换行符,请确保在替换中所需的 \、& 或换行符之前使用 \。"
    • 请注意,sed 必须看到 '\&amp;'。你必须让反斜杠越过 shell,这会使事情变得非常复杂。
    【解决方案2】:

    除了特殊字符之外,您还可以使命令更安全、更短:

    • 如果您的sed 支持-i(就地替换),则不需要mv
    • 为避免为其余命令设置IFS,您可以限制其范围
    • $html 中转义&amp;

    结果:

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

    如果它不适合您,请添加一个示例。可能还有其他特殊字符需要转义。

    【讨论】:

      【解决方案3】:

      使用任意字符作为命令分隔符,这里是一个例子:

      sed -Ei "s|$k|$j|g" filename.txt
      

      【讨论】:

        猜你喜欢
        • 2013-09-28
        • 1970-01-01
        • 2012-12-11
        • 2021-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-19
        相关资源
        最近更新 更多