Linux Shell 编程基础 简化自己的工作批量运行命令

Linux Shell 编程基础 简化自己的工作批量运行命令

生物信息入门到精通必修基础课:linux系统使用生信基础课合集推荐linux命令处理生物大数据

Shell是什么?

shell本身是一个命令解释器,介于操作系统的内核(kernel)态和用户态之间,可以执行系统调用及系统命令等,让用户以此来与操作系统实现互动。同时,它也用来指一种计算机程序语言(类似于C、Python等)。一个shell程序一般被称为一个脚本。

Shell语言的流派

目前,shell主要有两大流派:

sh:

        burne shell (sh)

        burne again shell (bash)

csh:

        c shell (csh)

        tc shell (tcsh)

        korn shell (ksh)

目前,大部分Linux系统预设的shell都是bash。

Shell 编程概述

在 Linux 下有一门脚本语言叫做:Shell 脚本,这个脚本语言可以帮助我们简化很多工作,例如批量运行一些命令等,所以还是很有必要学习它的基本用法的,一个简单的 hello.sh 脚本像下面这样。

#!/bin/bash 

echo "Hello World"

第一行 #!/bin/bash 标识该 Shell 脚本由哪个 Shell 解释:/bin/bash     。 将上面的两行内容写到文件hello.sh中,就可以执行了:

执行shell脚本方法1

#如果没有  第一行的:#!/bin/bash,可以这样直接执行
sh ./hello.sh

执行shell脚本方法2赋予权限才可以执行

# 赋予可执行权限
chmod a+x hello.sh

# 执行
./hello.sh

# 结果
Hello World

Shell 变量

Shell 变量分为 3 种: 
1. 用户自定义变量 
2. 预定义变量 
3. 环境变量


1. 用户自定义变量


定义变量需要注意下面 2 点: 
1. 等号前后不要有空格:NUM=10 
2. 一般变量名用大写:M=1

使用 $VAR 调用变量:

VAR="Hello Shell"
echo $VAR

注意:变量定义直接给变量取名字,字符串中有空格等特殊字符需要用引号引起来,这样VAR变量中存储了一个字符串,再次调用变量的值需要加$符号:

定义变量前缀:常见有这 3 个前缀: 
1. unset:删除变量 
2. readonly:标记只读变量 
3. export:指定全局变量

#!/bin/bash 

# 定义普通变量,没有特殊字符或者空格,可以不用引号
CITY=BEIJING

# 定义全局变量
export NAME=omicsclass

# 定义只读变量
readonly AGE=21

# 打印变量的值
echo $CITY
echo $NAME
echo $AGE

# 删除 CITY 变量
unset CITY
# 不会输出 BEIJING
echo $CITY

注:可将上面内容存入一个sh结尾的的文件中运行;

2. 预定义变量

预定义变量常用来获取命令行的输入,有下面这些:

  1. $0 :脚本文件名
  2. $1-9 :第 1-9 个命令行参数名
  3. $# :命令行参数个数
  4. $@ :所有命令行参数
  5. $* :所有命令行参数
  6. $? :前一个命令的退出状态,可用于获取函数返回值
  7. $$ :执行的进程 ID

一个例子:

#!/bin/bash 

echo "print $"
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$# = $#"
echo "\$@ = $@"
echo "\$* = $*"
echo "\$$ = $$"
echo "\$? = $?"

执行./hello.sh 1 2 3 4 5 的结果:

print $

# 程序名
$0 = ./hello.sh

# 第一个参数
$1 = 1

# 第二个参数
$2 = 2

# 一共有 5 个参数
$# = 5

# 打印出所有参数
$@ = 1 2 3 4 5

# 打印出所有参数
$* = 1 2 3 4 5

# 进程 ID
$$ = 9450

# 之前没有执行其他命令或者函数
$? = 0

3. 环境变量

环境变量默认就存在的变量,常用的有下面这几个: 
1. HOME:用户主目录 
2. PATH:系统环境变量 PATH 
3. TERM:当前终端 
4. UID:当前用户 ID 
5. PWD:当前工作目录,绝对路径

还是看例子:

#!/bin/bash

echo "print env"

echo $HOME
echo $PATH
echo $TERM
echo $PWD
echo $UID

运行结果:

print env

# 当前主目录
/home/orange

# PATH 环境变量
/home/orange/anaconda2/bin:后面还有很多

# 当前终端
xterm-256color

# 当前目录
/home/orange

# 用户 ID
1000

Shell 变量就介绍到这里,下面来介绍 Shell 的变量运算。

Shell 运算

我们经常需要在 Shell 脚本中计算,掌握基本的运算方法很有必要,下面就是 4 种比较常见的运算方法,功能都是将 m + 1: 
1. m=$[ m + 1 ] 
2. m=`expr $m + 1`   #注意 用 反引号  `   字符包起来  
3. let m=m+1 
4. m=$(( m + 1 ))

来看一个实际的例子:

#!/bin/bash 

m=1
m=$[ m + 1 ]
echo $m

m=`expr $m + 1`
echo $m

# 注意:+ 号左右不要加空格
let m=m+1
echo $m

m=$(( m + 1 ))
echo $m

运行结果:

2
3
4
5


Bash中的运算符总结

  1. Bash支持的运算符有:


    1. 数学运算符
    2. 关系运算符
    3. 布尔运算符
    4. 逻辑运算符
    5. 字符串运算符
    6. 文件测试运算符

数学运算符

+加法
-减法
*乘法
/除法
%取余
=赋值
==相等测试,相等则返回true
!=不相等测试,不相等则返回true

注意: 乘号*前边必须加反斜杠 \ 才能实现乘法运算

关系运算符  一般用于IF语句中判断

关系运算符只支持数字,不支持字符串,除非字符串的值是数字

-eq(equal) 检测两个数是否相等,相等则返回 true
-ne(not equal)检测两个数是否相等,不相等则返回 true
-gt(greater than)检测左边的数是否大于右边的,如果是,则返回 true
-lt(lower than) 检测左边的数是否小于右边的,如果是,则返回 true
-ge(greater equal)检测左边的数是否大于等于右边的,如果是,则返回 true
-le(lower equal) 检测左边的数是否小于等于右边的,如果是,则返回 true

布尔运算符

-a与运算,两个表达式都为 true 才返回 true
-o或运算,有一个表达式为 true 则返回 true
!非运算,表达式为 true 则返回 false,否则返回 true

逻辑运算符

&&逻辑与
II逻辑或

字符串运算符

=检测两个字符串是否相等,相等返回 true[ $a = $b ] 返回 false
!=检测两个字符串是否相等,不相等返回 true[ $a != $b ] 返回 true
-z检测字符串长度是否为0,为0返回 true[ -z $a ] 返回 false
-n检测字符串长度是否为0,不为0返回 true[ -n $a ] 返回 true
str_name检测字符串是否为空,不为空返回 true[ $a ] 返回 true

文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性

-b file检测文件是否是块设备文件,如果是,则返回 true
-c file检测文件是否是字符设备文件,如果是,则返回 true
-d file检测文件是否是目录,如果是,则返回 true
-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true
-g file检测文件是否设置了 SGID 位,如果是,则返回 true
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true
-p fill检测文件是否是命名管道,如果是,则返回 true
-u file检测文件是否设置了 SUID 位,如果是,则返回 true
-r file检测文件是否可读,如果是,则返回 true
-w file检测文件是否可写,如果是,则返回 true
-x file检测文件是否可执行,如果是,则返回 true
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true
-e file检测文件(包括目录)是否存在,如果是,则返回 true


1. if 语句

这个跟高级语言的 if - else - if 类似,只是格式有些不同而已,也来看个例子吧:

#!/bin/bash 

read VAR

# 使用 [] 判断,注意左右加空格

if [ $VAR -eq 10 ]
then
    echo "true"
else
    echo "false"
fi

#判断是否为文件
if [ -d  test.txt ]
then
    echo "true"
else
    echo "false"
fi



2. for 循环

这是一个 for 循环基本使用例子,挺简单的,有点类似 Python:

#!/bin/bash 

# 普通 for 循环
for ((i = 1; i <= 3; i++))
do
    echo $i
done


# VAR 依次代表每个元素 
for VAR in 1 2 3
do
    echo $VAR
done

# VAR 依次代表每个元素 ,{}产生连续数字
for VAR in {1..4}
do
    echo $VAR
done

#也可以写成一行,方便在命令行直接运行,注意空格和;号:

for VAR in 1 2 3;do  echo $VAR; done


运行结果:

1
2
3

3. while 循环

注意与 for 循环的区别:

#!/bin/bash 

VAR=1

# 如果 VAR 小于 10,就打印出来
while [ $VAR -lt 10 ]
do
    echo $VAR
#   VAR 自增 1
    VAR=$[ $VAR + 1 ]
done

运行结果:

1
2
3
4
5
6
7
8
9


4. break

Shell 中的 break 用法与高级语言相同,都是跳出循环,来看个例子:

#!/bin/bash 

for VAR in 1 2 3
do
#   如何 VAR 等于 2 就跳出循环
    if [ $VAR -eq 2 ]
    then
        break
    fi

    echo $VAR
done

运行结果:

1

5. continue

continue 用来跳过本次循环,进入下一次循环,再来看看上面的例子:

#!/bin/bash 

for VAR in 1 2 3
do
#   如果 VAR 等于 2,就跳过,直接进入下一次 VAR = 3 的循环 
    if [ $VAR -eq 2 ]
    then
        continue    
    fi

    echo $VAR
done

运行结果:

1
3

下面介绍 Shell 编程中比较重要的函数,好像每种编程语言的函数都很重要。


Shell 关键字

常用的关键字如下: 
1. echo:打印文字到屏幕 
2. exec:执行另一个 Shell 脚本 
4. expr:对整数型变量进行算术运算 
5. test:用于测试变量是否相等、 是否为空、文件类型等 
6. exit:退出

7.read:读标准输入


看个例子:

#!/bin/bash 

echo "Hello Shell"

# 读入变量
read VAR
echo "VAR is $VAR"

# 计算变量
expr $VAR - 5

# 测试字符串
test "Hello"="HelloWorld"

# 测试整数
test $VAR -eq 10

# 测试目录
test -d ./Android

# 执行其他 Shell 脚本
exec ./othershell.sh

# 退出
exit

运行前,你需要新建一个 othershell.sh 的文件,让它输出 I'm othershell,并且中途需要一次输入,我这里输入的是 10:

Hello Shell
10
VAR is 10
5
I'm othershell

学习任何一门语言都要了解它的变量定义方法,Shell 也不例外。


shell命令应用:


 其实我们的打开的linux的终端也是一个shell,上面很多命令不用存到文件中也可以直接在终端运行;下面举例shell编程的运用;


1.利用循环批量生成命令,分别存储到不同的文件:

for i in xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj  xak  xal  xam  xan;do echo "perl /share/work/huangls/piplines/01.script/kegg_update_get_anno.pl $i $i.anno $i.fa" >$i.sh;done

attachments-2019-09-k6Be3AuE5d70c5a1a1e4b.jpg


2.利用循环批量修改文件名:

这里我想把下面文件名字中红色中批量删除:

这里需要提前学习字符截取:https://www.omicsclass.com/article/378

attachments-2019-09-1hSkBrAI5d70bb2851051.jpg

for a in `ls *bam`;do  echo "mv $a ${a%%.*}.bam";done

#或者:

ls *bam|while read a;do echo "mv $a ${a%%.*}.bam";done

#或者将文件名字放到文件中:

for i in `cat file.txt|cut -f1`;do "mv $i ${i%%.*}.bam";done


当然批量改名字,linux中有rename 命令:https://www.omicsclass.com/article/1717




生物信息入门到精通必修基础课:linux系统使用生信基础课合集推荐linux命令处理生物大数据

  • 发表于 2019-09-05 14:58
  • 阅读 ( 7013 )
  • 分类:linux

0 条评论

请先 登录 后评论
omicsgene
omicsgene

生物信息

702 篇文章

作家榜 »

  1. omicsgene 702 文章
  2. 安生水 350 文章
  3. Daitoue 167 文章
  4. 生物女学霸 120 文章
  5. xun 82 文章
  6. 红橙子 78 文章
  7. rzx 76 文章
  8. CORNERSTONE 72 文章