6

我的角色有问题。我认为这是dos和unix之间的转换问题。

我有一个浮点值的变量。当我使用 echo 命令打印它时,我得到:

0.495959

但是当我尝试使用 bc 命令对该值进行操作时(我不确定如何编写 bc 命令)。

echo $mean *1000 |bc

我得到:

(standard_in) 1 : illegal character: ^M

我已经在我的 .sh 文件上使用了 dos2unix 命令。我认为这是因为我的变量具有 ^M 字符(未使用 echo 命令打印)

我怎样才能消除这个错误?

4

7 回答 7

13

我没有方便的 Cygwin,但是在常规 Bash 中,您可以使用该tr -d命令去除指定的字符,并且可以使用该$'...'符号在命令行参数中指定奇怪的字符(它就像一个普通的单引号字符串,除了它支持类似 C/Java/Perl/etc. 的转义序列)。所以这:

echo "$mean" * 1000 | tr -d $'\r' | bc

echo将在 from到的途中去掉回车符bc

你可能真的想运行这个:

mean=$(echo "$mean" | tr -d $'\r')

它将修改$mean以去除内部的任何回车符,然后您不必在以后使用它的命令中担心它。

(虽然也值得看一下设置$mean开始的代码。无论如何,最终如何在$mean其中包含回车?也许你可以解决这个问题。)

于 2011-11-29T19:59:46.463 回答
2

这有效:

${mean/^M/}

您可以通过键入 Ctrl-V 和 Ctrl-M 来获得 ^M。或者,或者:

${mean/$(printf "\r")/}

与@ruakh相比,此方法的好处是您在这里仅使用 bash 内置函数。第一个会更快,因为第二个将在子外壳内运行。

如果您只想“统一化”$mean:

mean="${mean/^M/}"

编辑:还有另一种方法:

${mean/$'\r'/}

于 2011-11-30T14:25:24.827 回答
2

正如您发现的那样,在 cygwin 中运行 Windows 的东西有一个令人讨厌的副作用 - 在 cygwin bash 变量中捕获 Windows 程序的输出也将捕获程序的 CR 输出。

明智地使用 d2u 可以避免这个问题 - 例如,

runtime="`mediainfo --Inform='Video;%Duration%' ${movie} | d2u`"

(如果没有 d2u,${runtime} 会在末尾添加一个 CR,这会导致您在将其提供给 'bc' 时看到的问题。)

于 2012-03-19T22:17:32.037 回答
1

也许您应该将脚本保存为 UNIX 格式而不是 DOS。

于 2011-11-29T19:41:07.460 回答
0

试试这个:

echo `echo $mean` *1000 |bc

如果 echo 真的没有打印它,它应该可以工作。

于 2011-11-29T19:43:30.637 回答
0

^M是一个回车符,在 Windows 中与换行符 ( \n) 一起用于指示下一行。但是,它不是在 UNIX 世界中完成的,因此bash不会将 at 视为特殊字符,并且会破坏语法。您需要做的是使用多种方法之一删除该字符。dos2unix例如,工具可以派上用场。

于 2011-11-29T19:46:21.353 回答
0

正如其他人指出的那样,这是一个 Windows 行尾问题。有很多方法可以解决这个问题,但问题是为什么会发生这种情况。

我可以在几个地方看到这种情况:

  • 这是一个在 Cygwin 启动时设置的 WINDOWS 环境变量。有时这些变量会在它们的末尾得到一个 CRLF。您提到这是这个变量的一个特殊问题,但您没有指定它的设置位置。

  • 您使用 Windows文本编辑器(如记事本Winpad )编辑了此文件。

永远不要使用文本编辑器来编辑程序。使用程序编辑器。如果您喜欢 VI,请下载在 Windows 上可用并在 Cygwin(和所有其他基于 Unix 的平台)上提供的VIM 。如果 VIM 不适合您,请尝试基于图形的Notepad++。这两个编辑器都处理行尾问题,并且可以在 Windows 中创建具有 Unix 行尾的脚本或在 Cygwin 中创建具有 Windows 行尾的文件。


  • 如果您使用 VIM,您可以执行以下操作来更改行尾并设置它们:

    • 要查看以当前文件结尾的行,请:set ff?在命令模式下键入 while。
    • 要为 Unix 设置行尾,请:set ff=unix在命令模式下键入 while。
    • 要为 Windows 设置行尾,请:set ff=dos在命令模式下键入 while。
  • 如果你使用记事本++

    • 您可以进入Edit-->EOL Conversion菜单项,查看您当前的行尾设置(未突出显示的那个)并更改它。
    • 要让 Notepad++ 使用 Unix 行尾作为默认值,请进入Settings-->Preferences菜单项。在对话框中,选择新建文档/默认目录选项卡。在作为新文档部分的一部分的格式部分中,选择所需的行尾。警告:不要选择作为选项。这甚至在 Mac 上都行不通。如果您有 Mac,请选择MacUnix
于 2011-11-30T14:44:17.897 回答