遍历目录中的文件,创建输出文件,linux
Iterate through files in a directory, create output files, linux
我试图遍历特定目录(称为序列)中的每个文件,并对每个文件执行两个函数。我知道函数('blastp' 和 'cat' 行)有效,因为我可以 运行 它们在单个文件上。通常我会有一个特定的文件名作为查询、输出等,但我正在尝试使用一个变量,以便循环可以处理许多文件。
(免责声明:我是编码新手。)我相信我 运行 在我的函数中尝试使用我的文件名时遇到了严重的问题。事实上,我的代码将执行,但它会创建一堆额外的意外文件。这就是我打算让脚本执行的操作:
第 1 行:遍历我的 "sequences" 目录中的每个文件。 (如果有帮助,所有这些都以“.fa”结尾。)
第 3 行:将文件名识别为变量。 (我知道,我知道,我想我做错了。)
第 4 行:运行 blastp 函数使用文件名作为 "query" 标志的参数,始终使用 "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".
如果我可以提供任何进一步的信息来澄清任何事情,请告诉我。
如果您只对 *.fa
个文件感兴趣,我会将您的输入限制为仅那些匹配的文件,如下所示:
for sequence in sequences/*.fa;
do
我可以向您提出以下改进建议:
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
我制作了更多中间变量,使用(希望)有意义的名称。
我使用 \
来转义行尾并允许将命令放在多行中。
我希望这能提高代码的可读性。
我还没有测试过。可能有错别字
如果您只想要以 .fa 结尾的文件,您应该使用 *.fa
。此外,如果您想将输出重定向到新文件夹,您需要使用
在某处创建这些目录
mkdir 'folder_name'
然后你需要将你的 -o 输出重定向到那些文件,像这样
'command' -o /path/to/output/folder
为了帮助您测试此脚本,您可以 运行 逐行逐行测试它们。在组合之前,您需要确保每一行都能独立工作。
最后一件事,小心使用冒号,它应该看起来像这样:
for filename in *.fa; do 'command'; done
我试图遍历特定目录(称为序列)中的每个文件,并对每个文件执行两个函数。我知道函数('blastp' 和 'cat' 行)有效,因为我可以 运行 它们在单个文件上。通常我会有一个特定的文件名作为查询、输出等,但我正在尝试使用一个变量,以便循环可以处理许多文件。
(免责声明:我是编码新手。)我相信我 运行 在我的函数中尝试使用我的文件名时遇到了严重的问题。事实上,我的代码将执行,但它会创建一堆额外的意外文件。这就是我打算让脚本执行的操作:
第 1 行:遍历我的 "sequences" 目录中的每个文件。 (如果有帮助,所有这些都以“.fa”结尾。)
第 3 行:将文件名识别为变量。 (我知道,我知道,我想我做错了。)
第 4 行:运行 blastp 函数使用文件名作为 "query" 标志的参数,始终使用 "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".
如果我可以提供任何进一步的信息来澄清任何事情,请告诉我。
如果您只对 *.fa
个文件感兴趣,我会将您的输入限制为仅那些匹配的文件,如下所示:
for sequence in sequences/*.fa;
do
我可以向您提出以下改进建议:
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
我制作了更多中间变量,使用(希望)有意义的名称。
我使用 \
来转义行尾并允许将命令放在多行中。
我希望这能提高代码的可读性。
我还没有测试过。可能有错别字
如果您只想要以 .fa 结尾的文件,您应该使用 *.fa
。此外,如果您想将输出重定向到新文件夹,您需要使用
mkdir 'folder_name'
然后你需要将你的 -o 输出重定向到那些文件,像这样
'command' -o /path/to/output/folder
为了帮助您测试此脚本,您可以 运行 逐行逐行测试它们。在组合之前,您需要确保每一行都能独立工作。
最后一件事,小心使用冒号,它应该看起来像这样:
for filename in *.fa; do 'command'; done