为什么会出现“第1行:$':\ r':命令未找到”?


13

我在笔记本电脑(DOS)上使用了Cygwin。我从同事和我的同事那里收集了一些脚本。我不是IT人员,也不了解Unix。我遵循同事的语法,能够处理一些简单的事情。

这些脚本在我的旧笔记本电脑上运行良好。我刚换了笔记本电脑,安装了Cygwin。当我运行脚本时,它们不起作用。这是我收到的错误消息的一个示例:

line 1: $':\r': command not found
line 5: syntax error near unexpected token `$'\r''
line 5: `fi

这是我脚本的前5行

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  

有人可以解释一下如何解决这个问题吗?

Answers:


29

您具有Windows样式的行尾。

no-op命令:改为读为:<carriage return>,显示为:\r或更完整的显示为$':\r'

运行dos2unix scriptname,你应该没事。


如果没有dos2unix,下面的命令几乎可以在任何地方工作(我在Windows的MobaXterm上进行了测试):

vi -b filename

然后在vi中输入:

:%s/\r$//
:x

你很好


在中vim,这是您在Cygwin上使用的功能vi,可以通过多种方式进行。另一个涉及fileformat设置,可以接受值dosunix。加载文件后显式更改

设置fileformat = unix
或使用以下方式写出文件时显式强制使用文件格式

:w + fileformat = unix

有关此的更多信息,请参见此处涉及该主题的许多问题和答案,包括:


只是想澄清一下,“ iter = 1”是我的计数器,它将用于数学模型的回合数,我的模型将在以后的第5行之外重复。我只张贴了前5行以错误信息。所有的意见和指示,不胜感激!
TPham'9

我刚刚尝试了建议的命令“ $ tr -d .....”,但是我的笔记本电脑出了点问题。它不会返回到“ $”,而是在屏幕上显示“>”。我必须使用contrl C才能退出。然后,我测试了脚本,以查看问题是否已解决,但仍然存在。抱歉,我对此领域的知识很少!我正在尝试利用我的脚本集合,因为它们确实对我的工作有很大帮助。感谢大家的耐心和对我的帮助。
TPham'9

@TPham,请参见编辑。如果可行,请确保在答案旁边使用对勾标记以“接受”它。(接受最能解决您问题的答案。) unix.stackexchange.com/help/someone-answers
通配符

1
对于初学者来说,作为单词的命令实际上并不比几乎完全是标点符号的神秘咒语复杂。不需要单独的答案。只需提及这个答案就vim可以以两种方式做到这一点,其中一种使用单词。或者,更好的是,指向此次级任务的答案比此页面上的任何答案都要详细得多,其中包括仅面向初学者的unix.stackexchange.com/questions/88811
JdeBP

1
需要注意的是vi -b\r是VIM扩展反正。没有POSIX,而不是在NVI,猫王的Solaris六...
斯特凡Chazelas

10

这是由于脚本已由使用DOS行尾的编辑器保存(例如,Notepad ++)。您将不得不从脚本中删除它们。

为此,请dos2unix在脚本文件上使用,或者

$ tr -d '\r' <script >script.new && mv script.new script

(这将从脚本中的任何位置删除所有回车符)


至于脚本中的代码:

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  

这可能看起来像

iter=1
if [ -f "./$iter.txt" ]; then
   rm "./$iter.txt"
fi

1.txt如果存在,这将从当前目录中删除该文件。该:命令不执行任何操作(几乎)并且可能被删除。该iter变量的值应尽可能使用$iter,并报价。然后,我可能会./说需要在当前目录中找到文件,因此比需要的更为明确。

如果你打算把它变成一个循环(这里,删除所有文件1.txt2.txt,..., 10.txt):

iter=1
while [ "$iter" -le 10 ]; then
    if [ -f "./$iter.txt" ]; then
        rm "./$iter.txt"
    fi
    iter=$(( iter + 1 ))
done

或者,如果我们感到偷偷摸摸/懒惰,

rm -f {1..10}.txt

在理解括号扩展的外壳中。


3
Notepad ++实际上可以选择使用Windows / Mac / Linux换行符。您只需要转到“编辑”菜单,然后转到“ EOL转换”->“ Unix(LF)”。或者,您可以双击显示在右下角的位置,Windows (CR LF)然后将其更改为Unix (LF)
jesse_b

谢谢大家的指导。想澄清一下:“ iter = 1”是我稍后用于主要目标的计数器,超出了第5行
。– TPham

@TPham不客气。我很无聊,拿走了您的代码,让我的大脑印象深刻。
库萨兰达

或者rm -f [1-9].txt 10.txt。但这在逻辑上并不完全等效,就好像没有文件1-9,而是有一个字面意义的文件[1-9].txt,它将被删除。:D
通配符

5

您的脚本的行尾错误。Windows使用CR + LF(\ r \ n),Unix使用LF(\ n),经典MacOS使用CR(\ r)。您需要使用文本编辑器或类似的独立工具来更改所有受影响文件的行尾dos2unix

FTP和版本控制系统(例如SVN)往往能够适当地转换行尾,因此您将来可能希望研究那些用于传输文件的选项。

如果这些文件不是要传输的,而是仅在一台机器上使用的,那么您将需要在首选的文本编辑器中找到行尾的设置。标榜为“面向程序员”的大多数人都会有这样的选择。


谢谢大家的有益指导。我刚刚尝试过dos2unix,但似乎我没有。将搜索并重试。
TPham'9

3

作为补充答案,让我添加一些注意事项/提示...

首先,对于常规文本文件,您可以使用file命令轻松确定它们的Unix或DOS行结尾。例如:

$ file test.txt
test.txt: ASCII text, with CRLF line terminators
$ dos2unix test.txt
dos2unix: converting file test.txt to Unix format...
$ file test.txt
test.txt: ASCII text

请注意我对的使用dos2unix。我强烈建议您安装它。根据您使用Cygwin的方式,您可能会发现需要经常进行此转换,以方便使用。更重要的是,没有像这里讨论的手动编辑那样出错的机会。

要安装,请启动Cygwin主可执行文件。这就是名称类似于setup-x86_64.exe的名称或类似名称的名称。确保您看到这样的屏幕:

在此处输入图片说明

由于已经完成了主要安装,因此应该能够一直单击“ 下一步”,直到出现选择屏幕。在下拉列表中选择Full,然后在搜索框中输入“ dos2”,然后选择工具,如下所示:

在此处输入图片说明

然后再次单击“ 下一步”,并完成安装。而已。玩得开心。除偶尔带来的不便外,Cygwin是一个很棒的软件包。


非常感谢您的指导B层!这个Stack Exchange组非常有帮助。我非常感谢您的支持。
TPham '17

1

如果没有dos2unix,也存在“翻转”

$ flip -u yourfilename.txt

将其翻转为使用Unix行尾。


1

我使用Notepad ++通过WinSCP连接到服务器来编辑bash(.sh)脚本
(要将WinSCP编辑器设置为Notepad ++:https : //winscp.net/eng/docs/ui_editor_preferences

这对于从服务器打开文件进行编辑/保存而不是“ Vim ”编辑器非常实用。
Notepad ++中打开文件时,双击底部状态栏上的第7列,然后选择“ Unix(LF) ”。

在此处输入图片说明

另外,您还必须通过顶部栏中的UTF-8中的编码->编码来更改第8个。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.