【问题标题】:Sed syntax difference MacOS vs GNUSed 语法差异 MacOS 与 GNU
【发布时间】:2021-02-06 15:54:58
【问题描述】:

我有以下代码可以在 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 脚本的新手,如果这个问题很愚蠢,请原谅。任何帮助将不胜感激!

【问题讨论】:

  • [[:&lt;:]] / [[:&gt;:]] 是有问题的标记。你想在这里做什么?它们被解析为命名字符类,例如[[:alnum:]],字母数字字符的类
  • [[:&lt;:]] 确实是无效的 char 类名。你想用it做什么?
  • @Aaron @vgersh99 此脚本将filename 中的src_op_lst 中的所有值替换为tgt_op_lst 中的相应值
  • 看来我的猜测是正确的:unix.stackexchange.com/a/393968/139867。我会发布答案
  • 哦,如果您不知道,ShellCheck 是一个很好的工具,可以帮助您查明脚本中的问题和不良做法。

标签: bash unix sed sh


【解决方案1】:

[[:&lt;:]][[:&gt;:]] 是 MacOS 的 sed 解释为定向词边界的标记:第一个让您检查是否在单词的开头匹配,第二个在单词的结尾。
这些可让您确保您替换的是整个单词而不是部分单词(例如,当您尝试将 pro 替换为 con 时,避免将 professor 更改为 confessor)。

在 GNU sed 中的确切等价物是 \&lt;\&gt;

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

【讨论】:

  • 感谢您的帮助,此解决方案对我有用!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 2011-01-05
  • 2011-10-22
  • 2015-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多