1 Star 0 Fork 0

ChrisWang / shell-study

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
linux-shell.md 38.36 KB
一键复制 编辑 原始数据 按行查看 历史
ChrisWang 提交于 2022-05-07 21:13 . 添加正则表达式

命令记忆

history #默认展示最近执行的1000条命令
!number #执行完history命令后,再使用此命令,表示执行历史命令中指定number的命令
!string #叹号后面跟命令,或命令的前几个字母,就会执行最近的完整的该命令
!$ # 表示上一条命令的最后一个参数
!! # 执行一一条命令,和 !-1效果相同

快捷键

ctrl+r #搜索历史命令

ctrl+d #登出

ctrl+a #回到命令开头,和home相同

ctrl+e #回到命令尾部,和end相同

ctrl+L #效果和clear相同

ctrl+u #删除光标之前的命令

ctrl+k #删除光标之后的命令

ctrl+s #锁屏,锁屏后,再输入,屏幕上没有显示,但实际已经输入了

ctrl+q #解锁屏幕,解锁之后,在锁屏状态下输入的内容会显示出来

后台运行

nohup	#在命令前加nohup,则表示命令在后台运行,即使关掉终端,再进来,该命令依然存在

screen  #记住当前操作视窗,方便下次进来时再进入该会话视窗
screen -S 名字	#给视察命名
screen -list  #显示目前所有的视窗作业
screen -r 视窗号  #打开后台的视窗
ctrl+c #是强制中断程序的执行,进程已经终止。
ctrl+z #是将任务中止(暂停的意思),但是此任务并没有结束,他仍然在进程中他只是维持挂起的状态,用户可以使用fg/bg操作继续前台或后台的任务,fg命令重新启动前台被中断的任务,bg命令把被中断的任务放在后台执行
#查看端口占用
netstat -tunlp|grep 57363

# !number 执行历史中第几条名称,先用命令history查看本地命令历史,如
history
!100

# !string 执行以该string开头的命令,如:
[root@localhost ~]# !da
date
2021年 12月 12日 星期日 16:31:02 CST

# !$ 上一个命令的最后一个参数,使用的时候,可以将这个参数传递给其他命令
# !! 执行上一个命令
# ctrl+R 上一个命令,使用时,输入字符,会提醒包含此字符的命令
# ctrl+a,移动光标到命令开始
# ctrl+e,移到光标到末尾
# ctrl+k,删除光标之后的命令
# ctrl+u,删除光标之前的命令
# ctrl+s,锁屏,执行的命令实际执行了,但是不显示
# ctrl+q,解锁屏幕
# ctrl+y,撤销操作

# 查看当前shell命令的别名
[root@localhost ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'

# 前后控制,如当在vim一个文件时,如果还没有编辑完,但又需要做其他事情时,可以先ESC,然后ctrl+z,则暂停编辑,若要回到vim编辑界面,fg回车即可

#重定向: 
cat 文件1 > 文件2 #将文件1的内容重定向到文件2中
cat 文件1 >> 文件2 #将文件1的内容换行追加到文件2中
cat << EOF #在屏幕上输入
echo "内容" >file1 #向file1添加一行
cat <<EOF>file2 # 向file2添加多行,以EOF结尾表示结束输入

#这条命令的作用是将标准输出1重定向到/dev/null中。 /dev/null代表linux的空设备文件,所有往这个文件里面写入的内容都会丢失,俗称“黑洞”。那么执行了>/dev/null之后,标准输出就会不再存在,没有任何地方能够找到输出的内容。
>/dev/null


# 管道符:将上一个命令的输出做为下一个命令的输入
ps aux | grep "test"  #在 ps aux中的結果中查找test
ps aux |tee grep "test"  #添加了tee之后,是将过程打印出来

#一行多个命令时,在两个命令之间可以添加分号;这个分号没有逻辑判断功能,即不管分号前的命令执行成功与否
#符号 && 也有 ; 号的功能,但有逻辑判断,即要 && 前的命令执行成功,后面的命令才会执行。
#符号 || ,当||前的命令返回失败,||后面的命令才会执行。

# 判断命令执行成功与否,使用下面命令,若返回0,则表示执行成功
echo $?

# 指定ping的次数,ping 百度一次
ping -c1 www.baidu.com

#通配符
# * 匹配任意多个字符;?匹配任意一个字符;
# []匹配括号中任意一个字符。如[a-z0-9],表示匹配任意一个字母或数字,若是[^a-z0-9],表示取反,即不匹配任意一个字母或数字
# 将shell命令用()括起来,表示在子shell中执行。
# {}表示集合,两个元素之间用 , 隔开
# \ 转义符,让通配符回归本意,测试下面命令,注意,echo后面的 -e 意思是可以解释后面的特殊字符,同样可以去掉 -e 再测试下
echo -e "atb"
echo -e "a\tb"
echo -e "anb"
echo -e "a\nb"

# 给字体/背景加颜色,字体颜色从30到37,背景颜色是从40到47
echo -e "\e[1;31mThis is a text."
# 去掉字体的颜色
echo -e "\e[0m"
# 只是让echo中的文字有颜色
echo -e "\e[1;31mThis is a text.\e[0m"

# 格式化输出文本
printf

# 显示最后一个目录的名称
[root@localhost shelljs]# basename /home/shelljs/
shelljs

# 显示目录
[root@localhost shelljs]# dirname /home/shelljs/
/home
类型 文件描述符 默认情况 对应文件句柄位置
标准输入(standard input) 0 从键盘获得输入 /proc/self/fd/0
标准输出(standard output) 1 输出到屏幕(即控制台) /proc/self/fd/1
错误输出(error output) 2 输出到屏幕(即控制台) /proc/self/fd/2
命令 介绍
command >filename 把标准输出重定向到新文件中
command 1>filename 同上
command >>filename 把标准输出追加到文件中
command 1>>filename 同上
command 2>filename 把标准错误重定向到新文件中
command 2>>filename 把标准错误追加到新文件中
命令 介绍
command <filename 以filename文件作为标准输入
command 0<filename 同上
command <<delimiter 从标准输入中读入,直到遇到delimiter分隔符

变量

  1. 变量必须以字母或下划线开头,不能以数字开头,区分大小;变量名和等号之间不准有空格。

  2. 变量引用: $变量名称 或 ${变量名}

  3. 查看变量:echo $变量名 (所有变量,包括自定义变量和环境变量)

  4. 使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

    #!/bin/bash
    myUrl="https://www.google.com"
    readonly myUrl
    myUrl="https://www.runoob.com"
  5. 使用 unset 命令可以删除变量。语法:unset variable_name

    #!/bin/sh
    
    myUrl="https://www.runoob.com"
    unset myUrl
    echo $myUrl
  6. 运行shell时,会同时存在三种变量:

    • 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
    • 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
    • shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
  7. 单引号

    str='this is a string'

    单引号字符串的限制:

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
  8. 双引号

    your_name="runoob"
    str="Hello, I know you are \"$your_name\"! \n"
    echo -e $str

    输出结果为:

    Hello, I know you are "runoob"! 

    双引号的优点:

    • 双引号里可以有变量
    • 双引号里可以出现转义字符
  9. 获取字符串长度:${#string},如:

    string="abcd"
    echo ${#string}
  10. 数组:在shell中,用括号表示数据,数组元素之间以空格分割:数组名=(元素1 元素2 元素3);

    也可以以指定下标的形式定义数组,如

    arrayVar[0]=this
    arrayVar[1]=is
    arrayVar[2]=a
    arrayVar[3]=array

    读取数组:${数组名[下标]}。使用@可以读取数组中的所有元素。

    读取数组的长度:length=${#array_name[@]}或length=${#array_name[*]},读取某个元素的长度:length=${#arrayVar[n]}

  11. 多行注释

    多行注释还可以使用以下格式:

    :*<<EOF
    注释内容...
    注释内容...
    注释内容...
    EOF*

    EOF 也可以使用其他符号:

    :<<'
    注释内容...
    注释内容...
    注释内容...
    '
    
    :<<!
    注释内容...
    注释内容...
    注释内容...
    !

传递参数

  1. ​ 在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$nn 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数。

    #!/bin/bash
    echo "我们的队员包括:$1 $2"

    执行上述脚本时,传入参数:

    ./variable.sh kobe hardon
  2. 另外,还有几个特殊字符用来处理参数:

    参数处理 说明
    $0 脚本名
    $# 传递到脚本的参数个数
    $* 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
    $$ 脚本运行的当前进程ID号
    $! 后台运行的最后一个进程的ID号
    $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
    $- 显示Shell使用的当前选项,与set命令功能相同。
    $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

当 $* 和 $@ 不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。

但是当它们被双引号" "包含时,就会有区别了:

  • "$*"会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。
  • "$@"仍然将每个参数都看作一份数据,彼此之间是独立的。

使用 echo 直接输出"$*""$@"做对比,是看不出区别的;但如果使用 for 循环来逐个输出数据,立即就能看出区别来。

#!/bin/bash

echo "print each param from \"\$*\""
for var in "$*"
do
    echo "$var"
done

echo "print each param from \"\$@\""
for var in "$@"
do
    echo "$var"
done

基本运算符

  1. 计算两个数之和:

    #!/bin/bash
    val=`expr 2 + 2`
    echo "2+2=$val"
    • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
    • 完整的表达式要被 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
  2. 其他运算,假定变量 a 为 10,变量 b 为 20

    运算符 说明 举例
    + 加法 expr $a + $b 结果为 30。
    - 减法 expr $a - $b 结果为 -10。
    * 乘法 expr $a \* $b 结果为 200。
    / 除法 expr $b / $a 结果为 2。
    % 取余 expr $b % $a 结果为 0。
    = 赋值 a=$b 把变量 b 的值赋给 a。
    == 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
    != 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。
  3. 关系运算符,关系运算符只支持数字,不支持字符串,除非字符串的值是数字。下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
    -ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
    -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
    -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
    -ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
    -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
  4. 布尔运算符,假定变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
    -o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
    -a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
  5. 逻辑运算符,假定变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    && 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
    || 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true
  6. 字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":

    运算符 说明 举例
    = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
    != 检测两个字符串是否不相等,不相等返回 true。 [ $a != $b ] 返回 true。
    -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
    -n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。
    $ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
  7. 文件测试运算符,用于检测 Unix 文件的各种属性

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

echo命令

#!/bin/bash
#显示普通字符串
echo "this is a string"

#显示转义字符
echo "\"this is a string\""

#显示变量
read name
echo "my name is $name"

#显示换行,-e 开启转义
echo -e "this is another column"

#显示不换行,-e 开启转义 \c不换行
echo -e "Hello \c"
echo " follow me"

#显示结果输出到文件
echo "this to the file">file1

#原样输出,使用单引号
echo '$hello\"'

#显示执行结果,使用``
echo `date`

printf命令

  1. 默认的printf不会像echo自动换行,需要手动添加\n

  2. 语法:printf format-string [arguments...]

    #!/bin/bash
     
    printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
    printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
    printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
    printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

    %s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。

    %-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

    %-4.2f 指格式化为小数,其中 .2 指保留2位小数。

  3. printf 的转义序列

    序列 说明
    \a 警告字符,通常为ASCII的BEL字符
    \b 后退
    \c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
    \f 换页(formfeed)
    \n 换行
    \r 回车(Carriage return)
    \t 水平制表符
    \v 垂直制表符
    \ 一个字面上的反斜杠字符
    \ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效
    \0ddd 表示1到3位的八进制值字符

    test命令

    1. 用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试

    2. 数值测试

      参数 说明
      -eq 等于则为真
      -ne 不等于则为真
      -gt 大于则为真
      -ge 大于等于则为真
      -lt 小于则为真
      -le 小于等于则为真
      #!/bin/bash
      num1=10
      num2=20
      if test $[num1] -eq $[num2]
      then
      	echo "两个数相等"
      else
      	echo "两个数不相等"
      fi

      代码中的 [] 执行基本的算数运算,如:

      #!/bin/bash
      
      a=5
      b=6
      
      result=$[a+b] # 注意等号两边不能有空格
      echo "result 为: $result" #结果为11
    3. 字符测试

      参数 说明
      = 等于则为真
      != 不相等则为真
      -z 字符串 字符串的长度为零则为真
      -n 字符串 字符串的长度不为零则为真
      #!/bin/bash
      num1="ru1noob"
      num2="runoob"
      if test $num1 = $num2
      then
          echo '两个字符串相等!'
      else
          echo '两个字符串不相等!'
      fi
    4. 文件测试

      参数 说明
      -e 文件名 如果文件存在则为真
      -r 文件名 如果文件存在且可读则为真
      -w 文件名 如果文件存在且可写则为真
      -x 文件名 如果文件存在且可执行则为真
      -s 文件名 如果文件存在且至少有一个字符则为真
      -d 文件名 如果文件存在且为目录则为真
      -f 文件名 如果文件存在且为普通文件则为真
      -c 文件名 如果文件存在且为字符型特殊文件则为真
      -b 文件名 如果文件存在且为块特殊文件则为真
      #!/bin/bash
      cd /bin
      if test -e ./bash
      then
          echo '文件已存在!'
      else
          echo '文件不存在!'
      fi

函数

  1. shell中函数的定义格式如下

    [ function ] funname [()]
    {
        action;
        [return int;]
    }
    • 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
    • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
  2. 一个实例:

    #!/bin/bash
    demoFun(){
        echo "这是我的第一个 shell 函数!"
    }
    echo "-----函数开始执行-----"
    demoFun
    echo "-----函数执行完毕-----"
  3. 带return的函数实例

    #!/bin/bash
    funWithReturn(){
        echo "这个函数会对输入的两个数字进行相加运算..."
        echo "输入第一个数字: "
        read aNum
        echo "输入第二个数字: "
        read anotherNum
        echo "两个数字分别为 $aNum$anotherNum !"
        return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"
    • 函数返回值在调用该函数后通过 $? 来获得
  4. 函数参数,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数

    #!/bin/bash
    
    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    • 注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

输入/输出重定向

  1. 重定向命令列表如下:

    命令 说明
    command > file 将输出重定向到 file。
    command < file 将输入重定向到 file。
    command >> file 将输出以追加的方式重定向到 file。
    n > file 将文件描述符为 n 的文件重定向到 file。
    n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
    n >& m 将输出文件 m 和 n 合并。
    n <& m 将输入文件 m 和 n 合并。
    << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
  2. Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。它的基本的形式如下:

    command << delimiter
        document
    delimiter
    • 它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
    • 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
    • 开始的delimiter前后的空格会被忽略掉。
  3. 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null

    $ command > /dev/null

    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

    如果希望屏蔽 stdout 和 stderr,可以这样写:

    $ command > /dev/null 2>&1

文件包含

  1. Shell 可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。

    Shell 文件包含的语法格式如下:

    . filename   # 注意点号(.)和文件名中间有一空格
    
    
    
    source filename
  2. 实例

创建两个 shell 脚本文件。

test1.sh 代码如下:

#!/bin/bash
url="http://www.runoob.com"

test2.sh 代码如下:

#!/bin/bash

#使用 . 号来引用test1.sh 文件
. ./test1.sh

# 或者使用以下包含文件代码
# source ./test1.sh

echo "菜鸟教程官网地址:$url"

接下来,我们为 test2.sh 添加可执行权限并执行:

$ chmod +x test2.sh 
$ ./test2.sh 

从键盘读入:read -p "提示信息" 变量名称

定义环境变量:export 变量名=变量值;将自定义变量转换为环境变量:export 自定义变量名;取消环境变量:unset 变量名;env:显示所有环境变量

# 变量替换:`命令`,$(命令) 均表示先执行 命令
[.root@localhost shelljs]# today1=`date +%F`
[root@localhost shelljs]# echo $today1
2021-12-19
[root@localhost shelljs]# today2=$(date +%F)
[root@localhost shelljs]# echo $today2
2021-12-19

read -p "提示信息: " 变量名

read -t 5 -p "提示信息: " 变量名 #输入状态停留5s,5s后输入状态消失;

read -n 2 变量名 #只能输入2个字符,-n指定输入字符的长度

read 变量1 变量2 变量3 # read后面可以跟多个变量,每个变量之间用空格分割

单引号和双引号

以单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。

以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。

条件测试

# [] 表示条件测试,如:
[ $? -eq 0 ] #判断上一条命令是否正确执行,注意前后的空格

文件操作

# 判断第一个参数是否是文献。$1表示第一个参数;-f判断是否是文件
if[ ! -f $1 ];then
	echo "error file"
fi

#统计文件行数
wc -l <file

正则表达式

basic

元字符

grep

grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

[root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename
选项与参数:
-A<显示行数>   --after-context=<显示行数>   #除了显示符合范本样式的那一列之外,并显示该行之后的内容。
-B<显示行数>   --before-context=<显示行数>   #除了显示符合样式的那一行之外,并显示该行之前的内容。
-E      --extended-regexp   #将样式为延伸的普通表示法来使用。
grep -E 选项可以用来扩展选项为正则表达式。 如果使用了grep 命令的选项-E,
则应该使用 | 来分割多个pattern,以此实现OR操作。
grep -E ‘pattern1|pattern2’ filename
-i    --ignore-case   #忽略字符大小写的差别。
-a   --text   #不要忽略二进制的数据。
-b   --byte-offset   #在显示符合样式的那一行之前,标示出该行第一个字符的编号。
-c    --count   #计算符合样式的列数。
-C<显示行数>    --context=<显示行数>或-<显示行数>   #除了显示符合样式的那一行之外,并显示该行之前后的内容。
-d <动作>      --directories=<动作>   #当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
-e<范本样式>  --regexp=<范本样式>   #指定字符串做为查找文件内容的样式。
-f<规则文件>  --file=<规则文件>   #指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
-F   --fixed-regexp   #将样式视为固定字符串的列表。
-G   --basic-regexp   #将样式视为普通的表示法来使用。
-h   --no-filename   #在显示符合样式的那一行之前,不标示该行所属的文件名称。
-H   --with-filename   #在显示符合样式的那一行之前,表示该行所属的文件名称。
-l    --file-with-matches   #列出文件内容符合指定的样式的文件名称。
-L   --files-without-match   #列出文件内容不符合指定的样式的文件名称。
-n   --line-number   #在显示符合样式的那一行之前,标示出该行的列数编号。
-q   --quiet或--silent   #不显示任何信息。
-r   --recursive   #此参数的效果和指定“-d recurse”参数相同。
-s   --no-messages   #不显示错误信息。
-v   --revert-match   #显示不包含匹配文本的所有行。
-V   --version   #显示版本信息。
-w   --word-regexp   #只显示全字符合的列。
-x    --line-regexp   #只显示全列符合的列。
-y   #此参数的效果和指定“-i”参数相同。

sed

简介

sed是非交互式的流编辑器。它不会修改文件,除非使用shell重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。 sed编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed便结束运行。sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。

sed 命令格式

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

命令选项

选项 功能
-e 直接在命令行模式上进行sed动作编辑,此为默认选项
-f 将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作
-i 直接修改文件内容
-n 只打印模式匹配的行
-r 支持扩展正则表达式
-h --help 显示帮助
-v --version 显示版本信息

常用命令

命令 功能
a   在当前行下面插入文本
i 在当前行上面插入文本
c 把选定的行改为新的文本
d 删除,删除选择的行
D 删除模板块的第一行
s 替换指定字符
h 拷贝模板块的内容到内存中的缓冲区
H 追加模板块的内容到内存中的缓冲区
g 获得内存缓冲区的内容,并替代当前模板块中的文本
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面
l 列表不能打印字符的清单
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码
p 打印模板块的行
P 打印模板块的第一行
q 退出Sed
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾
r file 从file中读行
t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾
T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾
w file 写并追加模板块到file末尾
W file 写并追加模板块的第一行到file末尾
! 表示后面的命令对所有没有被选定的行发生作用
= 打印当前行号
# 把注释扩展到下一个换行符以前

替换标记 (s 替换脚本命令)

标记 作用
n 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这时就用到这个标记
g 行内全局替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A
p 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用
w 将缓冲区中的内容写到指定的 file 文件中
x 互换模板块中的文本和缓冲区中的文本
y 把一个字符翻译为另外的字符(但是不用于正则表达式)
\n 匹配第n个子串,该子串之前在pattern中用 () 指定
& 已匹配字符串标记,用正则表达式匹配的内容进行替换
|转义(转义替换部分包含:&、\ 等)

元字符集

与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线"/"之间的模式。

如果要把正则表达式分隔符"/"改为另一个字符,比如o,只要在这个字符前加一个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:

sed -n '\o^Myop' datafile
元字符 作用 示例
^ 行首定位符 /^my/ 匹配所有以my开头的
$ 行尾定位符 /my$/ 匹配所有以my结尾的行
. 匹配除换行符外的单个字符 /m…y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行
* 匹配零个或多个前导字符 /my*/ 匹配包含字母m,后跟零个或多个y字母的行
[] 匹配指定字符组内的任一字符 /[Mm]y/ 匹配包含My或my的行
[^] 匹配不在指定字符组内的任一字符 /[^A-RT-Z]ed/ 匹配非A-R和T-Z开头,紧跟ed的行
…… 保存已匹配的字符 s/I(love)(you)/\2\1me Iloveyou -> youloveme
& 保存查找串以便在替换串中引用 s/love/&/,love -> love
< 词首定位符 /<my/ 匹配包含以my开头的单词的行
> 词尾定位符 /my>/ 匹配包含以my结尾的单词的行
x{m} 重复字符x,m次 /0{5}/匹配包含5个0的行
x{m,} 重复字符x,至少m次 /0{5,}/匹配至少有5个0的行
x{m,n} 重复字符x,至少m次,不多于n次 /0{5,10}/匹配5~10个0的行

sed支持的数据定位方法

格式 功能描述
number 直接根据行号匹配数据
first~step 从first开始,步长为step,匹配所有满足条件的数据行
$ 匹配最后一行
/regexp/ 使用正则表达式匹配数据行
\cregexpc 使用正则表达式匹配数据行,c可以是任意字符
addr1,addr2 直接使用行号定位,匹配从addr1到addr2的所有行
addr1,+N 使用行号定位,匹配从addr1开始及后面的N行

高级指令

sed在对数据进行编辑修改前需要先将读取的数据写入到模式空间中,sed还设计了一个保留空间,默认仅包含一个回车符。

  • h指令,把模式空间中的内容复制到保留空间,并覆盖保留空间中的回车符
  • H指令,把模式空间中的内容复制到保留空间,并不覆盖保留空间中的回车符
  • g指令,把保留空间的内容复制到模式空间,模式空间原有的数据被覆盖
  • G指令,把保留空间的内容追加到模式空间,模式空间原有的数据不被覆盖
  • x指令,将模式空间与保留空间中的数据直接交换
Shell
1
https://gitee.com/hoffmanwang/shell-study.git
git@gitee.com:hoffmanwang/shell-study.git
hoffmanwang
shell-study
shell-study
master

搜索帮助