29

我对 UNIX 编程非常非常陌生(通过终端在 MacOSX Mountain Lion 上运行)。我一直在学习生物信息学和分子方法课程的基础知识(我们有两个课程),我们最终将使用 perl 和 python 进行数据管理。无论如何,我们的任务是编写一个 shell 脚本来从一组文件中获取数据,并将其以特定程序 (Migrate-N) 可以读取的格式写入一个新文件。

当我在命令行中键入它们时,我已经获得了一些函数来独立完成我需要的功能,但是当我将它们全部放在一个脚本中并尝试运行它时,我得到了一个错误。以下是详细信息(我为篇幅道歉):

#! /bin/bash

grep -f Samples.NFCup.txt locus1.fasta > locus1.NFCup.txt
grep -f Samples.NFCup.txt locus2.fasta > locus2.NFCup.txt
grep -f Samples.NFCup.txt locus3.fasta > locus3.NFCup.txt
grep -f Samples.NFCup.txt locus4.fasta > locus4.NFCup.txt
grep -f Samples.NFCup.txt locus5.fasta > locus5.NFCup.txt
grep -f Samples.Salmon.txt locus1.fasta > locus1.Salmon.txt
grep -f Samples.Salmon.txt locus2.fasta > locus2.Salmon.txt
grep -f Samples.Salmon.txt locus3.fasta > locus3.Salmon.txt
grep -f Samples.Salmon.txt locus4.fasta > locus4.Salmon.txt
grep -f Samples.Salmon.txt locus5.fasta > locus5.Salmon.txt
grep -f Samples.Cascades.txt locus1.fasta > locus1.Cascades.txt
grep -f Samples.Cascades.txt locus2.fasta > locus2.Cascades.txt
grep -f Samples.Cascades.txt locus3.fasta > locus3.Cascades.txt
grep -f Samples.Cascades.txt locus4.fasta > locus4.Cascades.txt
grep -f Samples.Cascades.txt locus5.fasta > locus5.Cascades.txt

echo 3 5 Salex_melanopsis > Smelanopsis.mig
echo 656 708 847 1159 779 >> Smelanopsis.mig
echo 154 124 120 74 126 NFCup >> Smelanopsis.mig
cat locus1.NFCup.txt locus2.NFCup.txt locus3.NFCup.txt locus4.NFCup.txt locus5.NFCup.txt >> Smelanopsis.mig
echo 32 30 30 18 38 Salmon River >> Smelanopsis.mig
cat locus1.Salmon.txt locus2.Salmon.txt locus3.Salmon.txt locus4.Salmon.txt locus5.Salmon.txt >> Smelanopsis.mig
echo 56 52 24 29 48 Cascades >> Smelanopsis.mig
cat locus1.Cascades.txt locus2.Cascades.txt locus3.Cascades.txt locus4.Cascades.txt locus5.Cascades.txt >> Smelanopsis.mig

这一系列 grep 只是将每个位点的每个位点的 DNA 序列数据提取到新的文本文件中。Samples...txt 文件具有站点的样本 ID 号,.fasta 文件具有按样本 ID 组织的序列信息;如果我单独运行,grepping 在命令行中工作得很好。

第二组代码创建了我最终需要的实际新文件,该文件以 .mig 结尾。回波线是程序需要信息的计数数据(每个位点的碱基对、分析中的种群、每个位点的样本等)。猫线将通过站点数据将轨迹混合在一起,这些数据由回声线中指定的站点特定信息下方的所有 grepping 创建。毫无疑问,你得到了图片。

为了创建 shell 脚本,我一直在 Excel 中开始,这样我就可以轻松地复制粘贴/自动填充单元格,保存为制表符分隔的文本,然后在 TextWrangler 中打开该文本文件以删除制表符,然后再保存为 .sh 文件(行中断:Unix (LF) 和编码:Unicode (UTF-8)) 与脚本中使用的所有文件位于同一目录中。我已经尝试使用chmod +x FILENAME.shchmod u+x FILENAME.sh尝试确保它是可执行的,但无济于事。即使我将脚本缩减为一个 grep 行(使用 #! /bin/bash 第一行),我也无法让它工作。当我直接在命令行中键入它时,这个过程只需要一点时间,因为这些文件都不大于 160KB,有些文件明显更小。这是我输入的内容以及我尝试运行文件时得到的内容(HW 是正确的目录)

localhost:HW Mirel$ MigrateNshell.sh
-bash: MigrateNshell.sh: command not found

我已经陷入僵局两天了,所以任何输入将不胜感激!谢谢!!

4

12 回答 12

45

出于安全原因,shell 不会在当前目录(默认情况下)搜索可执行文件。您必须具体bash说明您的脚本位于当前目录 ( .) 中:

$ ./MigrateNshell.sh
于 2013-05-13T19:55:18.883 回答
23

将第一行更改为 Marc B 指出的以下内容

#!/bin/bash 

然后将脚本标记为可执行并从命令行执行

chmod +x MigrateNshell.sh
./MigrateNshell.sh

或者简单地从命令行执行 bash,将脚本作为参数传递

/bin/bash MigrateNshell.sh
于 2013-07-20T04:32:43.187 回答
16

确保您没有使用“PATH”作为变量,这将覆盖环境变量的现有 PATH。

于 2015-09-21T11:05:50.770 回答
10

也尝试dos2unix使用 shell 脚本,因为有时它有 Windows 行尾并且 shell 无法识别它。

$ dos2unix MigrateNshell.sh

这有时会有所帮助。

于 2013-12-10T11:46:17.413 回答
4

尝试chmod u+x MigrateNshell.sh

于 2016-01-15T02:29:22.457 回答
3

Unix 有一个名为的变量PATH,它是查找命令的目录列表。

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/david/bin

如果我foo在命令行键入命令,我的 shell 将首先查看是否有可执行命令/usr/local/bin/foo。如果有,它将执行/usr/local/bin/foo. 如果没有,它将查看是否有可执行命令/usr/bin/foo,如果不存在,它将查看是否/bin/foo存在等,直到到达/Users/david/bin/foo.

如果它在任何这些目录中都找不到命令foo,它会告诉我command not found

有几种方法可以处理这个问题:

  • 使用该命令bash foo,因为foo它是一个 shell 脚本。
  • 执行命令时包含目录名称,例如/Users/david/fooor$PWD/foo或只是 plain ./foo
  • 更改您的$PATH变量以将包含您的命令的目录添加到 PATH。

您可以修改$HOME/.bash_profile$HOME/.profile如果.bash_profile不存在。我这样做是为了添加/usr/local/bin我在路径中首先放置的位置。这样,我可以覆盖操作系统中的标准命令。例如,我有 Ant 1.9.1,但 Mac 自带的是 Ant 1.8.4。我把我的ant命令放进去/usr/local/bin,所以我的版本ant将首先执行。我还在$HOME/binPATH 的末尾添加了我自己的命令。如果我有一个像您想要执行的文件,我会将它放在 $HOME/bin 中以执行它。

于 2013-06-28T21:00:08.113 回答
2

关于将shebang 行添加到脚本开头有一些很好的评论。我想添加一个使用env 命令的建议,以获得额外的可移植性。

虽然#!/bin/bash可能是您系统上的正确位置,但这并不普遍。此外,这可能不是用户的首选bash。 #!/usr/bin/env bash将选择在路径中找到的第一个 bash。

于 2015-01-12T16:57:28.960 回答
2
#! /bin/bash
  ^---

删除指示的空间。shebang应该是

#!/bin/bash
于 2013-05-13T19:28:29.247 回答
0

在您的 .profile 路径中添加以下行

PATH=$PATH:$HOME/bin:$Dir_where_script_exists

export PATH

现在您的脚本应该可以在没有./

拉吉达格拉

于 2014-07-31T23:46:50.350 回答
0

还要确保 /bin/bash 是 bash 的正确位置 .... 如果您从某处的示例中获取该行,它可能与您的特定服务器不匹配。如果你为 bash 指定了一个无效的位置,你就会遇到问题。

于 2013-10-28T17:07:23.257 回答
-1

我也是 shell 脚本的新手,但我遇到了同样的问题。确保在脚本的末尾有一个空行。否则它将无法正常工作。

于 2018-10-15T21:04:15.987 回答
-4

第一的:

chmod 777 ./MigrateNshell.sh

然后:

./MigrateNshell.sh

或者,将您的程序添加到 $PATH 变量中可识别的目录中。示例:路径变量示例 ,这将允许您在没有的情况下调用您的程序./

于 2013-06-28T20:11:19.577 回答