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

时间:2022-07-14 23:02:53

I am sorry for posting this but this is driving me crazy. I am very new to bash scripting and am really struggling. I have files with the following format 8_S58_L001.sorted.bam and I would like to take the first digit (8 in this case) from many files and generate a csv file. This will give me the order in which samples were processed by a downstream function. The script is as follows and it works, however I get an error (-bash: syntax error near unexpected token `done') everytime I run it and am struggling to understand why. So far I have spent 2 days trying to get to the bottom of it and have searched extensively through various forums.

我很抱歉发布这个,但这让我发疯。我是一个非常新的打击脚本,我真的很挣扎。我有以下格式8_S58_L001.sorted.bam的文件,我想从许多文件中取第一个数字(在这种情况下为8)并生成一个csv文件。这将给出下游功能处理样品的顺序。该脚本如下,它可以正常工作,但每次运行它时都会出现错误(-bash:语法错误接近意外令牌'完成')并且很难理解原因。到目前为止,我花了两天时间试图深入了解并通过各种论坛进行了广泛的搜索。

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

If I just run

如果我跑了

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

Then I get the desired output and no errors but if it is incorporated within an do statement I get the above error. I am hoping to incorporate this into a larger script so I want to deal with this error first.

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

I should say that this is being run on a linux based cluster.

我应该说这是在基于Linux的集群上运行。

Can someone with more experience tell me where I am going wrong.

有经验的人可以告诉我哪里出错了。

Thanks in advance

提前致谢

Sam

2 个解决方案

#1


0  

bash doesn't have a do statement, and done is a reserved word when it is the first word in a command.

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

So in

do
  something
  something
done

do is a syntax error. do is only useful in the context of for and while loops, where it serves to separate the condition from the body of the loop.

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

Since you're reporting a syntax error on the done as opposed to the do, my guess is that you've let Windows line-endings creep into your file. Bash doesn't regard the \r (CR) character as special, so if your file actually contains do\r, then that will be considered to be the name of an external command.

由于您在完成时报告了语法错误,而不是do,我的猜测是您已经让Windows行结尾进入您的文件。 Bash不会将\ r(CR)字符视为特殊字符,因此如果您的文件实际包含do \ r,那么这将被视为外部命令的名称。

#2


0  

You should be aware that grep .bam$ doesn't do what you are expecting it to do. The dot is a grep wildcard which matches any single character, so the pattern .bam$ will match any string of 4 or more characters that ends in "bam". If you are trying to match all strings that end in ".bam", you should escape the dot and write grep "\.bam$"

你应该知道grep .bam $没有做你期望它做的事情。点是一个grep通配符,匹配任何单个字符,因此模式.bam $将匹配任何以“bam”结尾的4个或更多字符的字符串。如果您尝试匹配以“.bam”结尾的所有字符串,则应该转义该点并写入grep“\ .bam $”

But as a previous commenter correctly noted, you should be using shell wildcards (ls *.bam) instead of grep (ls | grep .bam$)

但正如之前的评论者所说,你应该使用shell通配符(ls * .bam)而不是grep(ls | grep .bam $)

#1


0  

bash doesn't have a do statement, and done is a reserved word when it is the first word in a command.

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

So in

do
  something
  something
done

do is a syntax error. do is only useful in the context of for and while loops, where it serves to separate the condition from the body of the loop.

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

Since you're reporting a syntax error on the done as opposed to the do, my guess is that you've let Windows line-endings creep into your file. Bash doesn't regard the \r (CR) character as special, so if your file actually contains do\r, then that will be considered to be the name of an external command.

由于您在完成时报告了语法错误,而不是do,我的猜测是您已经让Windows行结尾进入您的文件。 Bash不会将\ r(CR)字符视为特殊字符,因此如果您的文件实际包含do \ r,那么这将被视为外部命令的名称。

#2


0  

You should be aware that grep .bam$ doesn't do what you are expecting it to do. The dot is a grep wildcard which matches any single character, so the pattern .bam$ will match any string of 4 or more characters that ends in "bam". If you are trying to match all strings that end in ".bam", you should escape the dot and write grep "\.bam$"

你应该知道grep .bam $没有做你期望它做的事情。点是一个grep通配符,匹配任何单个字符,因此模式.bam $将匹配任何以“bam”结尾的4个或更多字符的字符串。如果您尝试匹配以“.bam”结尾的所有字符串,则应该转义该点并写入grep“\ .bam $”

But as a previous commenter correctly noted, you should be using shell wildcards (ls *.bam) instead of grep (ls | grep .bam$)

但正如之前的评论者所说,你应该使用shell通配符(ls * .bam)而不是grep(ls | grep .bam $)