首页 > 解决方案 > Sed 语法差异 MacOS 与 GNU

问题描述

我有以下代码可以在 MacOS 上完美运行,但不能在 GNU 上运行(我正在使用 MinGW):

filename=$1
iter_count=$((${#src_op_lst[@]} -1))
for i in $(eval echo "{0..$iter_count}");do
    echo "Checking File :" $filename
    sed -i "" "s/[[:<:]]"${src_op_lst[$i]}"[[:>:]]/"${tgt_op_lst[$i]}"/g" $filename
done

我想原因是sed语法不同,但我不知道如何让它在 GNU 上工作。我尝试使用sed -i -e ...,但 sed 给了我以下错误:-e expression #1, char 50: Invalid character class name.

我对 bash 脚本很陌生,如果这个问题很愚蠢,请原谅。任何帮助将不胜感激!

标签: bashunixsedsh

解决方案


[[:<:]]并且[[:>:]]是 MacOSsed解释为定向词边界的标记:第一个让您检查您在单词开头是否匹配,第二个在单词结尾。
这些可让您确保您替换的是整个单词而不是部分单词(例如,当您尝试替换时避免更改professor为)。confessorprocon

GNU sed 中的确切等价物是\<and \>

但是,作为熟悉正则表达式但不一定熟悉无数不同实现的人,我建议您使用更常见\b的而不是同时使用\<and \>
这是一个无方向的单词边界,如果您位于单词的开头或结尾,它将匹配。它会在您的情况下(并且在大多数情况下)产生完全相同的结果,并且未来的维护者将更有可能熟悉它,而不会经历您刚刚经历的挣扎。


推荐阅读