【问题标题】:What is the purpose of the "-" in sh script line: ext="$(echo $ext | sed 's/\./\\./' -)"sh 脚本行中“-”的用途是什么: ext="$(echo $ext | sed 's/\./\\./' -)"
【发布时间】:2013-02-08 21:27:32
【问题描述】:

我正在将一个显然是使用sed 的 GNU 实现编写的 sh 脚本移植到sed 的 BSD 实现。脚本中带有原始注释的确切行是:

# escape dot in file extension to grep it
ext="$(echo $ext | sed 's/\./\\./' -)"

我能够重现以下结果(显然我没有用尽ext 的所有可能性值):

ext=.h; ext="$(echo $ext | sed 's/\./\\./' -)"; echo [$ext]

使用 GNU 的 sed 实现,将返回以下内容:

[\.h]

使用 BSD 的 sed 实现返回以下内容:

sed: -: No such file or directory
[]

对于sed 的两个实现,执行ext=.h; ext="$(echo $ext | sed 's/\./\\./')"; echo [$ext] 返回[\.h]

我查看了 GNU 和 BSD 的 sed 的手册页没有发现任何关于尾随“-”的信息。用“-”搜索sed 也不是很有成效。

“-”是错字吗? $ext 的某些意外值是否需要“-”? 问题不在于sed,而是sh

谁能告诉我我应该看什么,或者更好地解释一下“-”的目的是什么?

【问题讨论】:

标签: sed gnu sh bsd


【解决方案1】:

在我的系统上,该语法没有记录在手册页中,但它在 “信息”页面:

sed 选项... [脚本] [输入文件...]

如果你没有指定 INPUTFILE,或者如果 INPUTFILE 是 -',sed' 过滤标准输入的内容。

鉴于这种特殊用法,我认为您可以省略“-”,它应该 还在工作。

【讨论】:

    【解决方案2】:

    您的具体问题得到了回答,但您的脚本全错了。看看这个:

    # escape dot in file extension to grep it
    ext="$(echo $ext | sed 's/\./\\./')"
    

    主要问题是:

    1. 您没有引用您的变量 ($ext),因此它将通过文件名扩展,如果它包含空格,则将作为多个参数而不是 1 传递给 echo。请改为:

      ext="$(echo "$ext" | sed 's/\./\\./')"
      
    2. 您正在使用一个外部命令 (sed) 和一个管道来做一些 shell 自己可以做的事情。改为这样做:

      ext="${ext/./\.}"
      
    3. 最糟糕的是:您正在转义变量中的 RE 元字符 (.),因此您可以将其传递给 grep 以对其进行 RE 搜索,就好像它是一个字符串一样 - 这没有任何意义并且在您的变量可能包含 RE 元字符的任何组合的一般情况下变得难以处理。只需进行字符串搜索而不是 RE 搜索,您无需转义任何内容。不要执行上述任何一个替换命令,然后执行其中任何一个而不是 grep "$ext" file

      grep -F "$ext" file
      fgrep "$ext" file
      awk -v ext="$ext" 'index($0,ext)' file
      

    【讨论】:

    • 他的剧本很好。 #1。也许 ext 没有问题字符(可能是扩展名)。 #2。不!这不在 POSIX 中(仅限 bash)。 #3。 fgrep/grep-F 的可移植性也较差,需要精细的运行时检测(参见 autoconf 中的 AC_PROG_FGREP!)。您是否要编写他需要在它们之间进行选择的代码..? OP 明确写了一个可移植的 shell 脚本,根本没有提到 bash,那你为什么要告诉他用 bashisms 替换可移植的结构呢?
    • @NicholasWilson - #1 - 当您可以简单地编写脚本来避免出现问题时,希望您不会遇到常见问题是荒谬的。 #2 - 正确,不是每个 shell 都支持这个结构,如果他的 shell 不支持它,他可以做一些比调用外部工具和管道更好的事情。 #3 fgrep/grep -F 绝对没问题,但如果你对它们有异议,那么请使用 awk 替代方案,因为所有 3 个替代方案都搜索字符串而不是 RE,这很重要,并且根本不需要解决第 2 点。
    • @NicholasWilson - 我建议您阅读 Chris Johnson (amazon.com/Shell-Scripting-Recipes-Problem-Solution-Approach/dp/…) 所著的“Shell Scripting Recipes: A Problem-Solution Approach”一书,以帮助您理解这些问题。
    • 干杯。作为回报,我建议您阅读“便携式 shell 的 Autoconf 指南”,以了解那些不生活在 bash 世界中的人的感受,例如,在我支持的某些平台上,如果实现失败,如何在 fgrep/grep-F 之间进行选择。 (总的来说,您对 #1 的看法是正确的,但告诉他他的“剧本全错”有点过分了。)
    • 你似乎错过了他的剧本全错的要点。他应该简单地使用单行 fgrep 或 awk 解决方案来搜索字符串,而不是他拼凑在一起试图逃避 RE 元字符的其他东西,这样他就可以使用 grep 使用 RE 搜索,但让 grep 认为它正在搜索一串!而且他需要在执行此操作时正确引用他的 shell 变量。
    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    相关资源
    最近更新 更多