shell脚本在linux中应用广泛,之前一直选用python写脚本来进行一些文件操作,但是最后发现shell脚本非常方便,所以特意来学习下皮毛,便于提高自己效率
1. 定义变量
country="China"
Number=100
##注意
##变量名和等号之间不能有空格
##若有调用变量,则加$即可,可perl一样
## 输出 country, 用echo即可
echo $country
2. 字符串
## 单引号
# 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
# 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
## 双引号
# 双引号里可以有变量
country="China"
echo "hello, $country"
# 双引号里可以出现转义字符
## 提取字符串长度,#号即可
string="abcd"
echo ${#string} #输出 4
## 提取子字符串; string
string="alibaba is a great company"
echo ${string:1:4} #输出liba
## 查找子字符串; index
string="alibaba is a great company"
echo `expr index "$string" is`
3. 处理路径的字符串
## 获取文件名; basename
basename /home/xiaoming/1.txt
结果 1.txt
## 获取多个路径,参数-a
basename -a /home/xiaoming/1.txt /home/ye/2.txt
结果:1.txt
2.txt
## 去掉文件名的后缀,参数 -s
basename -s .txt /home/xiaoming/1.txt
结果:1
##或者
basename /home/xiaoming/1.txt .txt
## 获取路径 dirname
dirname /home/xiaoming/1.txt
结果:/home/xiaoming
4. if语句
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi
## 也可以一行表示,一行则需要添加分号 ;
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
5. for循环
## 显示主目录下以 .bash 开头的文件
#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
## 读取文件含有fq的文件,并对其进行压缩; linux中用grep等
for file in $(ls |grep fq)
do
bgzip -f $file
done
## 读取reads,进行hisat2比对
for ((i=56;i<=58;i++));do hisat2 -t -x genome -1 SRR35899${i}.sra_1.fastq.gz -2 SRR35899${i}.sra_2.fastq.gz -S SRR35899${i}.sam ;done
##或则
for i in {56..58};do hisat2 -t -x genome -1 SRR35899${i}.sra_1.fastq.gz -2 SRR35899${i}.sra_2.fastq.gz -S SRR35899${i}.sam ;done
6. 外接参数
#!/bin/sh
name=$1
echo "The name is ${name}"
# 运行
./test.sh XiaoMing
The name is XiaoMing
# $1 表示第一个参数,$0为程序本身
7. 一次性添加多个样本输入一命令行
## 将24个染色体raw.vcf 利用GatherVcfs合并时,可以将多个vcf文件循环输出得到一个整体的变量即可
gatk GatherVcfs $(for i in {1..22} X Y;do echo "-I Test.chr${i}.raw.vcf";done) -O Test_gather.raw.vcf
8. 判断字符串是否为空
vi test.sh
test=
if [-z "$test"]
then
echo "Empty"
else
echo "NOT empty"
fi
#运行
./test.sh
Empty
##
-z 判断字符串是否为空,若为空则为真;
注意,对字符串比较添加双引号
9. 对字符串进行替换
将/output/merge_367_330.maker.outputI1/merge_367_330_master_datastore_index.log录下的merge_367_330_master_datastore_index.log后面_master_datastore_index.log去掉
vi test.sh
#!usr/bin/bash
maker_log=/output/merge_367_330.maker.outputI1/merge_367_330_master_datastore_index.log
name=$(basename "$maker_log" |sed 's/_master_datastore_index.log//'g)
echo ${name}_all.gff
10. 当shell中变量与awk冲突
比如现在有一个文本
1 Chr1 2
2 Chr2 3
3 Chr1 4
我想根据染色体提取对应信息
for i in Chr1;do awk '($2=='$i'){print $0}' test >new;done
# 上面命令不可行,因为$i 为新增加的变量,而不是awk命令里面的,所以再次用双引号扩起来
for i in Chr1;do awk '($2=="'$I'"){print $0}' test >new;done
head new
1 Chr1 2
3 Chr1 4
10. 加法,大于,或...
## 加法
a=10
c=$(($a+1))
echo $c
# 结果为11
# 或(||) 且(&&)
a=0
b=1
if [ $a ==1 ] || [ $b ==1 ]
then
echo 'good'
fi
11. 截取字符串
例子:Var=niub/idezi/fuchuan
- ‘#’ 去除左边信息 (*/去除左边‘/’(第一次出现)及之前信息 )
echo ${Var#*/}
idezi/fuchuan
- ‘##’ 去除左边信息 (*/去除左边‘/’(最后一次出现)及之前信息 )
echo ${Var##*/}
fuchuan
- ‘%%’ 去除右边信息 (*/去除右边‘/’(第一次出现)及之后信息 )
echo ${Var%/*}
niub/idezi
- ‘%%’ 去除右边信息 (*/去除右边‘/’(最后一次出现)及之后信息 )
echo ${Var%%/*}
niub
- 给定坐标截取
# 0表示左边第一个,6表示截取长度为6;省略6,则截取到结束
echo ${Var:0:6}
niub/I
# 右侧截取,从右侧第7位截取,到结束(和python 列表取字符串类似i[-1]
echo ${Var:0-7}
fuchuan
12. 变量中含有变量
gff1=test1.gff3
gff2=test2.gff3
for i in {1..2}
do
eval echo \$gff$I
done
13 判断文件是否存在,并终止程序
query_seq=query.fa
if [[ ! -f ${query_seq} ]]
then
echo -e "Error, ${query_seq} doesn't exist"
exit
fi
其中,-f 为是否为常规文件,-d 为是否为文件夹
网友评论