【linux编程】如何写shell脚本

【linux编程】如何写shell脚本_第1张图片
shell编程

开头

#!/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



- 比对的参数需要根据具体情况修改,

- 要求具有特定的目录构造

- 缺少日志信息输出,不利于调试

你可能感兴趣的:(【linux编程】如何写shell脚本)