如何确定哪个'\'导致错误?

时间:2014-08-02 18:43:10

标签: macos bash shell sed

我正在使用Makefile,其目标是缺少配方,导致make失败。我正在尝试使用bash脚本中的sed修补Makefile,sed未能在\周围声明问题。该脚本提供了下载,解压缩,修补和构建源代码的方法。

想法是查看lldbPluginSystemRuntimeMacOSX.a是否存在配方,如果找不到,则将其添加到特定位置。因此需要使用前导选项卡和尾部斜杠添加配方。

执行以下操作时:

# Determine if Apple
IS_DARWIN=`uname -s | egrep -i -c "Darwin"`
if [ $IS_DARWIN -ne 0 ]; then
  OTHER_OPTIONS=" --enable-libcpp"
fi

# Fix LLDB on OS X
if [ $IS_DARWIN -ne 0 ]; then
  cp Missing-Makefile llvm/tools/lldb/source/Plugins/SystemRuntime/MacOSX/Makefile
  chmod a+x llvm/tools/lldb/source/Plugins/SystemRuntime/MacOSX/Makefile

  COUNT=`cat llvm/tools/lldb/lib/Makefile | egrep -i -c lldbPluginSystemRuntimeMacOSX`
  echo *****COUNT: $COUNT*****

  if [ $COUNT -eq 0 ]; then
    sed -i '' "97i \tlldbPluginSystemRuntimeMacOSX.a \\" llvm/tools/lldb/lib/Makefile
  fi
fi

该代码段输出以下错误:

*****COUNT: 0*****
sed: 1: "97i \tlldbPluginSystemR ...": extra characters after \ at the end of i command

注意 :我在OS X上,这意味着sed不是BSD sed,而不是Linux {{1 }}。 OS X是它自己的世界。

我无法解决确切的问题。我已尝试在每个Using sed to insert TABs的标签中添加三个斜杠,但这会导致两个斜杠出现类似的错误。我也尝试过Nunk的2条斜线的建议,没有任何乐趣。看来猜测问题并不是最好的方法。

我能说的最好,没有详细的模式或其他方法可以在OS X上从sed获取详细信息。

问题:如何确定导致问题的sed?是否有可能确定问题斜线?

4 个答案:

答案 0 :(得分:2)

你确实需要一个实际的文字换行符。

我经常使用cat调试器:-)或者有时会使用更高级的vis版本(例如,vis -w在MacOS上执行此操作)以查看输入的内容,但是在这种情况下,你需要检查参数而不是stdin,这使得它更棘手。幸运的是echo "$@" | vis ...就足够了:

  sed -i '' '97i\ 
TABCHARlldbPluginSystemRuntimeMacOSX.a \\ 
' llvm/tools/lldb/lib/Makefile

变为:

echo '97i\ 
TABCHARlldbPluginSystemRuntimeMacOSX.a \\ 
' llvm/tools/lldb/lib/Makefile | vis -w

,喂给sh(普通老sh,这里真的不需要bash)实例,给我:

sh-3.2$ echo '97i\ 
> TABCHARlldbPluginSystemRuntimeMacOSX.a \\ 
> ' llvm/tools/lldb/lib/Makefile | vis -w
97i\\\040\^JTABCHARlldbPluginSystemRuntimeMacOSX.a\040\\\040\^J\040llvm/tools/lldb/lib/Makefile\^Jsh-3.2$

不是非常可读,但确实显示此处的反斜杠换行符后面有一个空格(\040位于\\和{{1}之间}})。删除它会使\^J正常,只要这实际上是通过的。

鉴于现代shell,您可以使用sed可读地编码内容:

$'...'

(请记住,文字反斜杠在sh-3.2$ echo $'magic: i\\\n\tstuff' | vis -w magic:\040i\\\^J\^Istuff\^Jsh-3.2$ 输出中编码为vis,文字换行符为\\,文字标签为\^J)。

还要记住,\^I添加换行符,而echo则不会,因此您可能需要更多内容:

sed

这里。

答案 1 :(得分:1)

似乎你需要逃避第一个反斜杠。尝试:

sed '97i \\tlldbPluginSystemRuntimeMacOSX.a \\' llvm/tools/lldb/lib/Makefile

对我来说,使用sed(GNU sed)4.2.2。

答案 2 :(得分:0)

sed的手册页(在OSX上)说:

[1addr]i\  
text        Write text to the standard output.

所以首先要做的是在97i之后的反斜杠之后添加换行符然后看起来TAB字符的\t是有问题的,所以我会用占位符替换它(比如{ {1}})并在最后用真正的标签替换它。

导致类似:

TABCHAR

(第二个if [ $COUNT -eq 0 ]; then sed -i '' '97i\ TABCHARlldbPluginSystemRuntimeMacOSX.a \\ ' llvm/tools/lldb/lib/Makefile sed -i '' 's/TABCHAR/ /' llvm/tools/lldb/lib/Makefile fi 中用TABCHAR替换的空格是文字制表符。

请注意,您可能无法成功复制和粘贴此代码,换行符和反斜杠非常重要,可能会搞砸。

答案 3 :(得分:0)

我建议在命令周围使用单引号而不是双引号并将其更改为:

sed -i '' '97i\    tlldbPluginSystemRuntimeMacOSX.a \\' llvm/tools/lldb/lib/Makefile
               ^ literal tab character

请注意,i\命令需要自己的反斜杠\。如果要使用\t转义序列来表示制表符,则还需要使用扩展模式-E

sed -E -i '' '97i\\tlldbPluginSystemRuntimeMacOSX.a \\' llvm/tools/lldb/lib/Makefile