-bash: 脚本中意外标记“完成”附近的语法错误

-bash: syntax error near unexpected token `done' in script

我很抱歉发布这个,但这让我发疯。我对 bash 脚本编写还很陌生,真的很挣扎。我有以下格式的文件 8_S58_L001.sorted.bam 并且我想从许多文件中获取第一个数字(在本例中为 8)并生成一个 csv 文件。这将给我下游功能处理样本的顺序。 该脚本如下所示并且可以正常工作,但是每次我 运行 它时我都会收到错误消息(-bash:意外标记“完成”附近的语法错误)并且我很难理解为什么。到目前为止,我已经花了 2 天时间试图深入了解它,并通过各种论坛进行了广泛搜索。

do
test=$(ls -LR | grep .bam$| sed 's/_.*//'| awk '{print}' ORS=',' | sed 's/*$//')
echo $test>../SampleOrder/fileOrder2.csv
done

如果我只是 运行

test=$(ls -LR | grep .bam$| sed 's/_.*//'| awk '{print}' ORS=',' | sed 's/*$//')
echo $test>../SampleOrder/fileOrder2.csv

然后我得到了想要的输出并且没有错误,但是如果它包含在 do 语句中我会得到上面的错误。我希望将它合并到一个更大的脚本中,所以我想先处理这个错误。

我应该说这是 运行 基于 linux 的集群。

有经验的人可以告诉我哪里错了吗?

提前致谢

山姆

bash 没有 do 语句,done 是命令中第一个单词时的保留字。

所以在

do
  something
  something
done

do 是语法错误。 do 仅在 forwhile 循环的上下文中有用,它用于将条件与循环主体分开。

由于您在 done 而非 do 上报告了语法错误,我猜您让 Windows 行结尾悄悄进入了您的文件. Bash 不认为 \r (CR) 字符是特殊的,因此如果您的文件实际上包含 do\r,那么将认为是外部命令的名称。

您应该知道 grep .bam$ 并没有按照您的预期进行。点是匹配任何单个字符的 grep 通配符,因此模式 .bam$ 将匹配任何以 "bam" 结尾的 4 个或更多字符的字符串。如果你试图匹配所有以“.bam”结尾的字符串,你应该转义点并写成 grep "\.bam$"

但正如之前的评论者正确指出的那样,您应该使用 shell 通配符 (ls *.bam) 而不是 grep (ls | grep .bam$)