我在bash中做了一些事情,脚本占用了三个文件名并处理它们并将最终结果存储在第三个文件中。
脚本是:
#!/bin/bash
#clear
echo -n " Bam File "
read BamFile
echo -n " Region File "
read BedFile
echo -n " Output File "
read OutFile
awk '{print $1 "\t" $2 "\t" $3 "\t" $3-$2}' < $BedFile >Temp
coverageBed -abam $BamFile -b $BedFile -counts > bases
awk '{print $4 }' <bases >tempbases
paste -d "\t" Temp tempbases >TtTemp
samtools view -c -F 260 $BamFile > totalNumReads
cat totalNumReads | awk '{print $1}'>tags
tag=`cat tags`
echo " Number of tags present in file = $tag"
awk '{print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $5/($4/1000* "'$tag'"/1000000) } '<TtTemp > $OutFile
此脚本效果很好。
但是,我想对脚本进行以下调整。
我不想一个一个地询问文件名,而是想在开始时提供它们
类似的东西:
process.bash -bam BamFile.bam -region RegFile -Out OutFile
其中process.bash是我的脚本,并且在开始时提供了三个文件。
有人可以帮我这么做。
谢谢
答案 0 :(得分:2)
您可以测试这样的参数:
#!/bin/bash
bam=null
reg=null
out=null
while [[ $# -gt 1 ]]; do
arg="$1"
case $arg in
--bam)
bam=$2
shift
;;
--reg)
reg=$2
shift
;;
--out)
out=$2
shift
;;
--help)
helpmenu
;;
*)
shift
;;
esac
shift
done
function helpmenu() {
echo -e "Your help text\n"
exit 0
}
# Continue your script with the variables bam, reg and out
# ...
然后你可以像
一样使用你的脚本 $ process.bash --bam BamFile.bam --reg RegFile --out OutFile
那就是它。
您可以使用功能制作帮助菜单等内容。例如,我调用下面定义的函数helpmenu
。然后它只是在回显后存在脚本。
编辑:
由于在这篇文章的评论中进行了长时间的讨论,让我说清楚一些事情:
在我看来,像我在帖子中那样处理每手的参数要强得多。原因是,它支持各种un * x系统(例如非POSIX系统)。
然后,因为声明只支持长命令:也支持短命令。我只是没有将它们添加到代码中,因为它没有被OP询问。例如,如果您希望能够传递-b file
以及--bam file
等文件,则只需相应地更改案例陈述:
-b|--bam)
bam=$2
shift
;;
我没有看到这个答案有什么问题,因为它提供了所要求的功能。我自己在所有脚本中使用这种方法,并且从未遇到过这样的问题。
答案 1 :(得分:2)
虽然循环遍历参数也是一个很好的解决方案,我想使用getopts
命令提供解决方案。
我使用内部getopts
,而不是扩展,它有几个限制(即你只能使用单个字符来引用参数)。
接下来,我提供了我发现的最类似的解决方案。
#!/bin/bash
##############################
# HELPER METHODS
##############################
# Parses the script arguments
getArgs() {
# Parse Options
while getopts :hvb:r:o:-: flag; do
# Treat the argument
case "$flag" in
h)
# Display help
usage
;;
v)
# Display version
show_version
;;
b)
bamFile=${OPTARG}
;;
r)
regFile=${OPTARG}
;;
o)
outFile=${OPTARG}
;;
-)
# Check more complex arguments of the form --OPT, --OPT=VALUE
case "$OPTARG" in
help)
# Display help
usage
;;
version)
show_version
;;
bam=*)
# Get bam filename
bamFile=$(echo $OPTARG | sed -e 's/bam=//g')
;;
reg=*)
# Get bam filename
regFile=$(echo $OPTARG | sed -e 's/reg=//g')
;;
out=*)
# Get bam filename
outFile=$(echo $OPTARG | sed -e 's/out=//g')
;;
*)
# Flag didn't match any patern. Raise exception
display_error "${OPTARG}"
;;
esac
;;
*)
# Flag didn't match any patern. Raise exception
display_error "${OPTARG}"
;;
esac
done
}
usage() {
echo "Usage: "
exit 0
}
show_version() {
echo "Version: "
exit 0
}
display_error() {
local argument=$1
echo "[ERROR] Bad argument $argument"
exit 1
}
##############################
# MAIN PROCESS
##############################
getArgs "$@"
echo "[DEBUG] BAM $bamFile"
echo "[DEBUG] REG $regFile"
echo "[DEBUG] OUT $outFile"
awk '{ print $1 "\t" $2 "\t" $3 "\t" $3-$2 }' < $bedFile > Temp
coverageBed -abam $bamFile -b $bedFile -counts > bases
awk '{print $4 }' < bases > tempbases
paste -d "\t" Temp tempbases > TtTemp
samtools view -c -F 260 $bamFile > totalNumReads
cat totalNumReads | awk '{ print $1 }' > tags
tag=$(cat tags)
echo " Number of tags present in file = $tag"
awk '{ print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $5/($4/1000* "'$tag'"/1000000) }' < TtTemp > $outFile
一些示例输出:
$./process.sh -v
Version:
$./process.sh --version
Version:
$./process.sh -h
Usage:
$./process.sh --help
Usage:
$./process.sh -b bamfile -r regfile -o outfile
[DEBUG] BAM bamfile
[DEBUG] REG regfile
[DEBUG] OUT outfile
$./process.sh --bam=bamfile -rregfile --out=outfile
[DEBUG] BAM bamfile
[DEBUG] REG regfile
[DEBUG] OUT outfile
正如我所说,有一些限制。例如:
$./process.sh --bam=bamfile -rregfile -out=outfile
[DEBUG] BAM bamfile
[DEBUG] REG regfile
[DEBUG] OUT ut=outfile
虽然用户试图指定其他内容,但它是有效的条目。从我的角度来看,你应该在解析之后和开始这个过程之前检查bamFile,regFile,outFile值。