如何在目录中对筛选出的gz文件应用自定义BASH函数?
如何在目录中对筛选出的gz文件应用自定义BASH函数?
你遇到的问题很典型——find通过-exec启动的sh是一个全新的独立Shell进程,它根本不知道你在当前Shell里定义的fastq_countGzReads函数,所以才会抛出“sh cannot open fastq_countGzReads”的错误。下面给你几种实用的解决办法:
方法一:导出函数到子Shell
Bash支持把函数导出到环境变量中,让子进程也能访问到这个函数,步骤很简单:
- 先导出你的自定义函数:
export -f fastq_countGzReads
- 然后修改
find的执行命令,指定用Bash来执行(而不是sh,因为sh对函数导出的支持有限):
find . -iname "*gz" -exec bash -c 'fastq_countGzReads "$0"' {} \;
这里的$0会对应find找到的每个文件名,完美把文件路径传给你的函数。
方法二:把函数做成独立可执行脚本
如果这个计数工具你会经常用,不如把它封装成独立脚本,用起来更省心:
- 创建一个名为
fastq_countGzReads.sh的文件,写入以下内容:
#!/bin/bash # 统计gz压缩fastq文件的reads数 echo $(( $(wc -l < <(zcat "$1")) / 4 ))
我顺便优化了原函数的写法,用进程替换替代管道,效率会更高一点。
2. 给脚本添加执行权限:
chmod +x fastq_countGzReads.sh
- 现在直接用
find调用这个脚本就行:
find . -iname "*gz" -exec ./fastq_countGzReads.sh {} \;
如果脚本不在当前工作目录,记得写完整路径,比如/home/yourname/scripts/fastq_countGzReads.sh。
方法三:结合xargs批量处理
如果你想批量处理文件,用xargs配合Bash执行的方式效率会更高:
- 同样先导出函数:
export -f fastq_countGzReads
- 然后执行这条命令:
find . -iname "*gz" | xargs -I {} bash -c 'fastq_countGzReads "{}"'
-I {}表示用找到的每个文件名替换命令里的{},实现批量调用函数。
备注:内容来源于stack exchange,提问作者Peter Pisher
相关产品推荐
相关产品推荐

