如何编写支持文件与标准输入(stdin)读取的脚本?以及让NCBI BLAST+的blastn脚本读取stdin输入的替代方案
如何让脚本同时支持文件输入和标准输入(stdin)——以NCBI BLAST+的blastn为例
嘿,这个问题问得很实用!我来分两部分给你拆解:先讲通用脚本怎么实现同时支持文件和stdin输入,再针对blastn的场景给你具体的解决方案。
一、通用脚本的实现逻辑
不管是写Shell脚本还是Python这类脚本,核心思路都是先检查是否传入了文件参数:
- 如果有指定文件名,就从该文件读取内容;
- 如果没有参数(或者参数是
-),就切换到标准输入(stdin)读取。
给你举两个常用的例子:
Shell脚本示例
#!/bin/bash # 简化版:用参数展开处理,${1:--}表示如果$1不存在就用"-" cat "${1:--}"
这个脚本既可以接受文件名参数(比如./script.sh input.txt),也可以直接从stdin读取(比如echo "test" | ./script.sh),完全符合你的需求。
Python脚本示例
import sys def get_input_content(): # 检查命令行是否传入文件名 if len(sys.argv) > 1: with open(sys.argv[1], 'r') as input_file: return input_file.read() # 没有传入文件就从stdin读取 return sys.stdin.read() if __name__ == "__main__": content = get_input_content() # 这里可以写后续处理逻辑 print(content)
二、针对blastn的具体解决方案
其实blastn并没有你想的那么“死板”,它遵循Unix工具的通用约定,有好几种不用临时文件的方法:
方法1:用-作为查询文件参数
直接把查询序列通过管道传给blastn,然后用-query -指定从stdin读取查询内容:
# 示例:传递FASTA格式的序列 echo ">my_query\nATCGATCGATCGAGCTAGCT" | blastn -query - -db your_target_database
这里的-query -就是告诉blastn:“我的查询序列来自标准输入”,完美替代临时文件。
方法2:用进程替换(Process Substitution)
如果你需要把字符串“伪装”成文件传给blastn,bash的进程替换功能很有用——它会创建一个临时伪文件(不会写到磁盘):
blastn -query <(echo ">my_query\nATCGATCGATCGAGCTAGCT") -db your_target_database
这种方式看起来像是给blastn传了一个真实文件名,但内容其实是实时生成的,非常适合这类需要文件名参数的工具。
方法3:用Here-Document直接传入
如果你的序列内容比较长,还可以用here-document的方式直接把内容重定向给blastn:
blastn -db your_target_database << EOF >my_query ATCGATCGATCGAGCTAGCT GGATCCGGATCCGGATCC EOF
这种写法不需要额外的管道,直接在命令行里写序列内容,非常直观。
内容的提问来源于stack exchange,提问作者BallLightning
相关产品推荐
相关产品推荐

