如何为调用GNU parallel的Shell脚本传递过滤参数?
问题描述
我用awk和GNU Parallel批量处理.csv.gz文件,根据第1列大于0.5、第2列小于1.5的规则过滤内容,最后合并输出到单个output.csv.gz文件。目前写了如下脚本myscript.sh:
#!/bin/bash doit() { pigz -dc $1 | awk -F, '$1>0.5 && $2<1.5' } export -f doit find $1 -name '*.csv.gz' | parallel doit | pigz > output.csv.gz
执行命令是:
./myscript.sh /path/to/files
现在想把过滤阈值0.5和1.5改成脚本参数,实现这样的执行方式:
./myscript.sh /path/to/files 0.5 1.5
解决方案
可以通过以下步骤修改脚本,实现阈值参数化:
- 参数校验:先检查脚本是否接收到足够的参数,避免因参数缺失导致错误
- 传递阈值到处理函数:将阈值作为参数传给
doit函数,确保awk能获取到动态阈值 - Parallel调用时传递参数:在Parallel的管道中把阈值传递给每个
doit进程
修改后的完整脚本如下:
#!/bin/bash # 检查参数数量是否足够 if [ $# -ne 3 ]; then echo "用法: $0 <文件路径> <阈值1(第1列大于该值)> <阈值2(第2列小于该值)>" exit 1 fi # 定义处理函数,接收文件名、阈值1、阈值2三个参数 doit() { local file="$1" local threshold1="$2" local threshold2="$3" pigz -dc "$file" | awk -F, -v t1="$threshold1" -v t2="$threshold2" '$1>t1 && $2<t2' } export -f doit # 查找文件并调用Parallel,传递阈值参数 find "$1" -name '*.csv.gz' | parallel doit {} "$2" "$3" | pigz > output.csv.gz
关键修改说明:
- 参数校验:用
if [ $# -ne 3 ]判断参数数量,不符合就输出用法提示并退出 - awk变量传递:用
-v t1="$threshold1"和-v t2="$threshold2"把Shell变量传给awk,避免直接拼接字符串导致的语法问题 - Parallel参数传递:
parallel doit {} "$2" "$3"中,{}代表find找到的每个文件名,后面跟着脚本接收的两个阈值参数,确保每个并行进程都能拿到正确的阈值 - 局部变量:在
doit函数里用local定义变量,避免变量污染全局环境
现在就可以按需求执行脚本了:
./myscript.sh /path/to/files 0.5 1.5
内容的提问来源于stack exchange,提问作者kiasari
相关产品推荐
相关产品推荐

