开头
#!/bin/bash
set -e
set -u
set -o pipeline
中间
将日常中不断重复的工作写到脚本中。但是为了脚本具有普遍适用性,所以要用到
变量和命令参数
条件语句
循环语句和文件名替换
# set work path
PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
work_dir=$1
sample_info=$2
reference=${work_dir}/data/reference/TAIR10_chr_all.fas
命令参数
就是命令后接的部分,例如cat some.file
的命令参数就是some.file。我们可以利用这个功能从外界传入自定义的内容。shell脚本以$0,$1,$2,$3..
分别代表命令自身,第一个参数,第二个参数,第三个参数等。
新建一个argument_test.sh,输入如下内容。
#! /bin/bash
echo "command is $0"
echo "first argument is $1"
echo "second argument is $2"
echo "third argument is $3"
运行结果:
Bash
$ bash argument_test.sh A B C
command is argument_test.sh
first argument is A
second argument is B
third argument is C
条件语句
正常情况下最好加上条件语句,提高脚本的适用性。
if [条件]
then
commands
else
comgmands
fi
[条件]可以用bash下的命令,例如
# 单个条件
if grep "pattern" some.file >/dev/null
then
echo "found 'pattern' in some.file"
fi
# 多个条件
# 或 || ; 与&& ;非 !
if grep 'pattern1' some.file > /dev/null &&
grep 'pattern2' some.file > dev/null
then
echo "found 'pattern1' and 'pattern2' in some.file"
fi
除了bash下的命令外,还可以用`test`或`[]`判断条件是否成立,如下
# -f 判断是否为文件
if test -f some.file
then
....
fi
# 或[] 记住里面的左右一定要有空格
if [ -f some.file ]
then
....
fi
《鸟叔的Linux的私房菜》第三版的380页中提高了许多判断方式,一般常用的如下:
| 测试的标志 | 代表意义 |
| ------------ | ------------ |
| -d | 是否为文件夹 |
| -f | 是否为文件 |
| -e | 文件是否存在 |
| -h | 是否为连接 |
| -w | 能否写入 |
| -x | 能否执行 |
| str1 = str2 | 字符是否相同 |
| str1 != str2 | 字符是否不相同 |
| -eq | 数值是否相等 |
| -ne | 数值是否不等 |
| -lt | 小于 |
| -gt | 大于 |
| -le | 小于等于 |
| -ge | 大于等于 |
一般而言,创建一个pipline处理文件需要三个步骤:
选择目标文件
使用指定命令处理目标文件
追踪处理后的输出文件
而循环语句就是在选择目标文件后,用于重复相同的指令处理目标文件,还可以记录输出文件。
其中选择目标文件有两种方式:1. 提供记录目标文件信息的文本,2.从含目标文件的文件夹内筛选。
方法1:
# 假设你现在在mbs-2017-4/script下
sample_info=sample.txt
sample_names=($(cut -f 1 "$sample_info" ))
echo "${sample_names[@]}"
BC.fg.reads1 BC.fg.reads2 BC.bg.reads1 BC.bg.reads2
说明 ${sample_names[@]}
的表示显示所有变量内容,我们可以选择特定的元素,将@
替换成0,1,2,3(以0开始),此外 ${#sample_names[@]}
表示共有多个元素, ${!sample_names[@]}
表示各个元素的索引。
方法2比较粗暴,直接利用通配符列出文件。
sample_names=$(ls *.fq)
for sample in ${sample_names[@]}
do
- 比对的参数需要根据具体情况修改,
- 要求具有特定的目录构造
- 缺少日志信息输出,不利于调试