2011-11-29 71 views
5

我有一個字符問題。我認爲這是dos和unix之間的轉換問題。Bash programmation(Cygwin):非法字符^ M

我有一個浮點值的變量。 當我用echo命令打印我得到:

0.495959 

但是,當我試圖讓與bc命令是值的操作(我不知道如何寫bc命令)。

echo $mean *1000 |bc 

我得到:

(standard_in) 1 : illegal character: ^M 

我已經在我的sh文件使用DOS2UNIX的命令。 我想這是因爲我的變量有^ M字符(不是用echo命令打印的)

我該如何消除這個錯誤?

+0

'$ mean'是如何獲得的? – netcoder

+0

使用ImageMagick「識別」命令。但是,因爲我在Windows上,它可能會以DOS格式而不是Unix格式輸出結果。什麼導致一個馬車角色被添加。? – Frencoo

+0

好的,但是你運行的命令是什麼,所以'$ mean'被填充了?像'mean = \'識別... \''...我們需要整條線。 – netcoder

回答

11

我沒有Cygwin的方便,但在常規Bash中,可以使用tr -d命令去除指定的字符,並且可以使用$'...'表示法在命令行參數中指定奇怪的字符(就像普通的單引號字符串,只是它支持C/Java/Perl /等轉義序列)。所以,這樣的:

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

將去掉回車符號的方式,從echobc

你可能真的要運行此:

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

將修改$mean裏面剔除任何回車符號,然後你將不必擔心在使用它以後的命令。

(雖然它也是值得考慮看看那臺$mean開始。如何$mean最終不得不在它回車的代碼啊?也許你可以解決這個問題。)

+0

Thans很多人,它的作品! – Frencoo

1

也許你應該將腳本保存爲UNIX格式而不是DOS格式。

+0

我已經使用dos2unix命令將其轉換。這是你的意思嗎? – Frencoo

+0

是的。我不知道爲什麼使用dos2unix不能解決您的問題。代碼看起來不錯。我試過了,它工作正常。但是,如果我在DOS模式下保存腳本,我會得到相同的錯誤:'(standard_in)1:非法字符:^ M'。通常我不使用dos2unix,只是因爲我更喜歡編輯器。要複製你的代碼,我使用[pspad](http://www.pspad.com)。它的免費,也許你可以試試看。 – loscuropresagio

+0

謝謝你我會嘗試pspad – Frencoo

0

試試這個:

echo `echo $mean` *1000 |bc 

如果真的回聲不打印,它應該工作。

+2

這是一個很好的想法,但它不會幫助。如果'$ mean'包含'^ M',並且Bash將'^ M'識別爲一個字詞分隔符(默認情況下它不*),那麼'echo $ mean * 1000'將會使'^ M ',因爲'$ mean'沒有被引用。如果*是*'echo',那就是添加'^ M',那麼它顯然不會工作(如你所知道的),如果變量'^ M'和Bash *不能識別它作爲一個單詞分隔符,那麼內部的'echo'將仍然打印'^ M',而外部的'echo'將重複它 - 沒有增加。 – ruakh

+0

@ruakh你是對的,我沒有想到它通過! – elias

0

^M是在Windows中使用的carriage return字符以及用於指示下一行的換行符(\n)字符。然而,它不是在UNIX世界中如何完成的,因此bash不會視爲特殊字符,並且會破壞語法。你需要做的是使用許多方法之一刪除該字符。例如,dos2unix工具可以派上用場。

+0

正如我所說,我已經在我的.sh文件中使用了dos2unix命令。 這是什麼意思或我必須以另一種方式使用? – Frencoo

2

該作品:

${mean/^M/}

您可以通過輸入Ctrl-V,然後按Ctrl-M來獲得^ M。或者,也可以使用:

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

這種方法相比,@ruakh的好處是,只有在這裏你正在使用bash內置插件。第一個將會更快,因爲第二個將在子shell中運行。

如果你只是想 「unixize」 $平均:

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

編輯:又一方式:

${mean/$'\r'/}

0

正如其他人所指出的那樣,這是Windows線結束問題。有很多方法可以解決這個問題,但問題是爲什麼這首先發生。

我可以看到這種情況出現在好幾個地方:

  • 這是當Cygwin的啓動已設置Windows環境變量。有時候這些變量會在它們的最後得到一個CRLF。你提到這是這個變量的一個特殊問題,但是你沒有指定它的設置。

  • 您編輯使用的是Windows 文本編輯這個文件好像記事本Winpad

切勿使用文本編輯器編輯程序。使用程序編輯器。如果你喜歡VI,下載VIM這是在Windows上可用,並在Cygwin(和所有其他基於Unix的平臺)。如果VIM不適合你,請嘗試更多圖形化的Notepad++。這兩種編輯器都處理行尾問題,並且可以在Windows中使用Unix行結尾創建腳本,或者在Cygwin中使用Windows行結尾創建腳本。


  • 如果你使用VIM,你可以做以下改變行結尾,並對其進行設置:

    • 要查看當前文件結束行,鍵入:set ff?而在命令模式。
    • 要設置結束於Unix的行,請在命令模式下鍵入:set ff=unix
    • 要設置結束於Windows的行,請在命令模式下鍵入:set ff=dos
  • 如果用記事本++

    • 您可以進入編輯 - > EOL轉換菜單項,然後看看你的結局設置當前行(它不是強調一個),並改變它。
    • 要讓Notepad ++使用Unix行尾作爲默認值,請進入設置 - >首選項菜單項。在對話框中,選擇新建文檔/默認目錄選項卡。在格式部分,它是新文檔部分的一部分,請選擇您想要的結束行。 警告:請勿選擇Mac作爲選項。這在Mac上甚至不起作用。如果您有Mac,請選擇Unix
+0

謝謝,我會試試看。順便說一句,我用的是寫字板,這可能會導致問題.. – Frencoo

1

Cygwin中運行Windows的東西有,你發現了一個討厭的副作用 - 捕獲Windows程序的輸出一個cygwin bash的變量也將捕捉程序輸出CR。

明智地使用D2U的避免了這一問題 - 例如,

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

(不D2U,$ {運行}將有CR上漲了年底,這會導致你看到的,當你給它的問題以'bc'爲例。)