遍历目录中的文件,创build输出文件,linux

我正在尝试迭代特定目录(称为序列)中的每个文件,并在每个文件上执行两个函数。 我知道这些函数('blastp'和'cat')起作用,因为我可以在单个文件上运行它们。 通常我会有一个特定的文件名作为查询,输出等,但我试图使用一个variables,所以循环可以通过许多文件工作。

(免责声明:我是新来的编码。)我相信,我遇到了严重的问题,试图在我的函数中使用我的文件名。 就这样,我的代码将会执行,但是它会创build一些额外的非预期文件。 这就是我的脚本所要做的:

第1行:遍历我的“序列”目录中的每个文件。 (所有这些都以“.fa”结尾,如果有帮助的话)

第3行:将文件名识别为variables。 (我知道,我知道,我认为我做了这个可怕的错误。)

第4行:使用文件名作为“查询”标志的参数运行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”。

如果我可以提供任何进一步的信息来澄清任何事情,请让我知道。

如果您只对*.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 

我做了更多的中间变量,(有希望)有意义的名字。 我用\来逃避行结束,并允许把命令放在几行。 我希望这可以提高代码的可读性。

我没有测试过。 可能有错别字。