我试图遍历特定目录中的每个文件(称为序列),并在每个文件上执行两个函数。我知道函数('blastp'和'cat'行)可以工作,因为我可以在单个文件上运行它们。通常我会有一个特定的文件名作为查询,输出等,但我正在尝试使用一个变量,因此循环可以处理许多文件。
(免责声明:我是编码的新手。)我相信我在尝试在我的函数中使用我的文件名时遇到了严重的问题。实际上,我的代码将执行,但它会创建一堆额外的非预期文件。这就是我打算让我的脚本做的事情:
第1行:遍历“sequences”目录中的每个文件。 (所有这些都以“.fa”结尾,如果这有用的话。)
第3行:将文件名识别为变量。 (我知道,我知道,我认为我做错了。)
第4行:使用文件名作为“query”标志的参数运行blastp函数,始终使用“database.faa”作为“db”标志的参数,并将结果输出到新文件中与初始文件具有相同的名称,但最后使用“.txt”。
第5行:将第4行输出文件的部分输出到一个新文件中,该文件与初始文件同名,但最后带有“_top_hits.txt”。
for sequence in ./sequences/{.,}*;
do
echo "$sequence";
blastp -query $sequence -db database.faa -out ${sequence}.txt -evalue 1e-10 -outfmt 7
cat ${sequence}.txt | awk '/hits found/{getline;print}' | grep -v "#">${sequence}_top_hits.txt
done
当我运行这段代码时,它给了我六个从目录中的每个文件派生的新文件(它们都在同一个目录中 - 我更喜欢将它们全部放在自己的文件夹中。我怎么能这样做?)。他们都是空的。它们的后缀是“.txt”,“。txt.txt”,“。txt_top_hits.txt”,“_ top_hits.txt”,“_ top_hits.txt.txt”和“_top_hits.txt_top_hits.txt”。
如果我可以提供任何进一步的信息以澄清任何事情,请告诉我。
答案 0 :(得分:3)
如果您只对START_STICKY
文件感兴趣,我会将您的输入限制为仅限于以下匹配文件:
*.fa
答案 1 :(得分:0)
我可以为您提出以下改进建议:
for fasta_file in ./sequences/*.fa # ";" is not necessary if you already have a new line for your "do"
do
# ${variable%something} is the part of $variable
# before the string "something"
# basename path/to/file is the name of the file
# without the full path
# $(some command) allows you to use the result of the command as a string
# Combining the above, we can form a string based on our fasta file
# This string can be useful to name stuff in a clean manner later
sequence_name=$(basename ${fasta_file%.fa})
echo ${sequence_name}
# Create a directory for the results for this sequence
# -p option avoids a failure in case the directory already exists
mkdir -p ${sequence_name}
# Define the name of the file for the results
# (including our previously created directory in its path)
blast_results=${sequence_name}/${sequence_name}_blast.txt
blastp -query ${fasta_file} -db database.faa \
-out ${blast_results} \
-evalue 1e-10 -outfmt 7
# Define a file name for the top hits
top_hits=${sequence_name}/${sequence_name}_top_hits.txt
# alternatively, using "%"
#top_hits=${blast_results%_blast.txt}_top_hits.txt
# No need to cat: awk can take a file as argument
awk '/hits found/{getline;print}' ${blast_results} \
| grep -v "#" > ${sequence_name}_top_hits.txt
done
我制作了更多的中间变量,(希望)有意义的名字。
我使用\
来转义行结束并允许将命令放在几行中。
我希望这可以提高代码的可读性。
我还没有接受过测试。可能存在拼写错误。
答案 2 :(得分:0)
如果只需要以.fa结尾的文件,则应该使用*.fa
。此外,如果要将输出重定向到新文件夹,则需要使用
mkdir 'folder_name'
然后,您需要将-o输出重定向到这些文件,例如
'command' -o /path/to/output/folder
为帮助您测试此脚本,可以逐行运行每一行对其进行测试。您需要确保每行在合并之前都能独立工作。
最后一件事,请谨慎使用冒号,它应类似于以下内容:
for filename in *.fa; do 'command'; done