Shell脚本的入门(一)

Shell脚本能极大简化那些简答而重复的工作,学会写Shell,我觉得可以。

Simple BB

为了简化工作量,我需要写个替换同名资源的脚本,看了一天的shell简单的写下我的思路
首先获取用于替换的资源的路径,然后生成一个临时文件A,遍历获取对应的文件名,重定向输出到A。
获取目标资源的路径,根据A中的行数进行循环find查找,找到就用cp命令替换,未找到的重定向输出到临时文件B
最后打印B的内容,remove临时文件。
其中对文本的处理使用了awk命令

脚本下载地址在我的github上 资源替换脚本


Shell介绍

Shell Script ,Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处理更强大,比用其他编程程序编辑的程序效率更高,它使用了Linux/Unix下的命令。
而我使用shell只是因为
我用的mac - -


Shell的工作原理

Shell可以被称作是脚本语言,因为它本身是不需要编译的,而是通过解释器解释之后再编译执行,和传统语言相比多了解释的过程所以效率会略差于传统的直接编译的语言。


Shell的创建

1.打开文本编辑工具,输入一下内容
#!/bin/bash echo "Hello World"
2.保存为 hello world.sh在目录 A
3.在终端cd到目录 A
4.终端输入chmod +x ./hello world.sh (这一步是给脚本添加权限)
5.执行脚本 ./hello world.sh 或者 直接把 hello world.sh拖入终端

这很简单,无图。


Shell中的变量

变量的定义

1
example="a1"

或者

1
example=a1

但是
example=a 1 并不等同于 example="a 1"
因为" "(空格)在shell中用作指令的间隔
example=a 1 其实只是将a负责给example 然后在输入了个1

这很重要,在很多赋值的时候不注意会导致获取到的变量并不是你期望的那样,别问我怎么知道的!

变量的访问

在变量前加上$

1
echo $example

Shell中的四则运算

1
2
3
4
$a + $b
$a - $b
$a \* $b
$a / $b

注意

乘法的时候需要进行转义
= 赋值时,前后无空格
而运算符号前后必须有空格


Shell中的其他运算符

=、==、!=、!、-o、-a

1
2
-o 或
-a 与

关系运算符

-eq 两个数相等返回true
-ne 两个数不相等返回true
-gt 左侧数大于右侧数返回true
-It 左侧数小于右侧数返回true
-ge 左侧数大于等于右侧数返回true
-le 左侧数小于等于右侧数返回true

字符串运算符

= 两个字符串相等返回true
!= 两个字符串不相等返回true
-z 字符串长度为0返回true
-n 字符串长度不为0返回true
-d file 检测文件是否是目录,如果是,则返回 true
-r file 检测文件是否可读,如果是,则返回 true
-w file 检测文件是否可写,如果是,则返回 true
-x file 检测文件是否可执行,如果是,则返回 true
-s file 检测文件是否为空(文件大小是否大于0,不为空返回 true
-e file 检测文件(包括目录)是否存在,如果是,则返回 true


Shell字符串操作


  mtext="hello"  #定义字符串
  mtext2="world"
  mtext3=$mtext" "$mtext2  #字符串的拼接
  echo $mtext3  #输出字符串
  echo ${#mtext3}  #输出字符串长度
  echo ${mtext3:1:4}  #截取字符串

Shell数组


  array=(1 2 3 4 5)  #定义数组
  array2=(aa bb cc dd ee)  #定义数组
  value=${array[3]}  #找到某一个下标的数,然后赋值
  echo $value  #打印
  value2=${array2[3]}  #找到某一个下标的数,然后赋值
  echo $value2  #打印
  length=${#array[* ]}  #获取数组长度
  echo $length

Shell输出


  echo

Shell的判断


  a=10
  b=20
  if [ $a == $b ]
  then
  echo "true"
  fi


  if [ $a == $b ]
  then
  echo "true"
  else
  echo "false"
  fi


  if [ $a == $b ]
  then
  echo "a is equal to b"
  elif [ $a -gt $b ]
  then
  echo "a is greater than b"
  elif [ $a -lt $b ]
  then
  echo "a is less than b"
  else
  echo "None of the condition met"
  fi

Shell中的test命令

1
2
3
4
5
6
7
8
9
10
  test $[num1] -eq $[num2]  #判断两个变量是否相等
test num1=num2 #判断两个数字是否相等


-e file 文件存在则返回真
-r file 文件存在并且可读则返回真
-w file 文件存在并且可写则返回真
-x file 文件存在并且可执行则返回真
-s file 文件存在并且内容不为空则返回真
-d file 文件目录存在则返回真

Shell中的循环

for循环


  for ((i=1;i<=10;i++)) 5="" 6="" 7="" 8="" 9="" do="" echo="" $i="" done="" for="" i="" in="" {1..5}="" file="" $home="" .bash*="" $file="" <="" code="">

while循环


  while [ $COUNTER -lt 5 ]
  do
  COUNTER=`expr $COUNTER + 1`
  echo $COUNTER
  done

  echo '请输入。。。'
  echo 'ctrl + d 即可停止该程序'
  while read FILM
  do
  echo "Yeah! great film the $FILM"
  done

跳出循环


  break  #跳出所有循环
  break n  #跳出第n层f循环
  continue  #跳出当前循环

Shell中的函数

无参数无返回值


  sysout(){
  echo "hello world"
  }

  sysout    
> 无参数有返回值

  test(){

  aNum=3
  anotherNum=5
  return $(($aNum+$anotherNum))
  }
  test
  result=$?
  echo $result
> 有参数有返回值

  test(){
  echo $1  #接收第一个参数
  echo $2  #接收第二个参数
  echo $3  #接收第三个参数
  echo $#  #接收到参数的个数
  echo $*  #接收到的所有参数
  }

  test aa bb cc    

Shell中的重定向


  $echo result > file  #将结果写入文件,结果不会在控制台展示,而是在文件中,覆盖写
  $echo result >> file  #将结果写入文件,结果不会在控制台展示,而是在文件中,追加写
  echo input < file  #获取输入流

Shell中的变量操作

awk 指令
获取指定行数的资源名字

1
sourceNameTemp=$(awk 'NR=="'$i'" {print;exit}' $OutputFile)

获取对应文件名

1
temp=${temp##*/}

清空文件

1
: > "$OutputFile"

常用的Linux命令

awk命令

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

基本结构

1
awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file

一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被单引号或双引号中

工作原理

第一步:执行BEGIN{ commands }语句块中的语句;
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{ commands }语句块。

BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。

END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

获取指定行数的文本

1
awk 'NR=="'$i'" {print;exit}' file

获取文件的行数

1
awk '{print NR}' "file"|tail -n1

关于awk的详细用法请参考 awk命令