shell学习笔记

SHELL学习

一、什么是shell

shell是一个程序,采用C语言编写。是用户和linux内核沟通的桥梁,是一种命令语言,也是一种解释性的编程语言。内核识别二进制语言。

kernel:为软件服务,接受软件或用户的指令驱动硬件,完成工作;

shell:命令解释器;

user:用户接口,对接用户。

二、SHELL的功能

​ 1.命令解释功能;

​ 2.启动程序;

​ 3.输入输出重定向;

​ 4.管道连接

​ 5.文件名置换

​ 6.变量维护

​ 7.环境控制

三、SHELL的语法

shell脚本就是将完成一个任务的所有的命令按照执行顺序的先后,自上而下写入到一个文本中,然后给予执行权限。

3.1.如何书写一个shell脚本

​ 1.命名要有意义

​ 2.注释用 #

​ 3.执行环境查询 which bash

​ 4.定义脚本的执行环境 #!/usr/bin/bash

​ 5.脚本带作者,书写时间,及脚本注释

3.2如何运行shell脚本

​ 1. 给权限 chomd 700 1.sh 然后执行 ./1.sh

  1. ​ bash 1.sh

  2. ​ sh 1.sh

3.2shell中的特殊字符

~       家目录

—     返回上一次的目录

!       执行历史命令       !!执行上一条命令     !数字         执行history里边的命令

$      变量中取内容      echo $USER

&      后台执行

‘*      星号 通配符,匹配所有

?     匹配一个字符

\       转义字符

· ·       反引号,命令中执行命令

’ ‘          单引号,字符串,不同于双引号,单引号不解释变量

“”           字符串,可以解释变量     echo "$USER"

3.3 SHELL中的管道应用

上一个命令的输出,是下一个命令的输入

[root@localhost opt]# cat /etc/passwd | grep "root"

3.4 SHELL 重定向

>       重定向输入,覆盖元数据

\>>      重定向输入,追加到末尾

<         重定向输出, wc <  /etc/passwd (不要操作系统文件)

<<        重定向追加输出

3.5 SHELL数学运算符

let赋值 (整数运算)

        let  c=2*3

        echo   $c

expr 只做整数运算

[root@localhost ~]# expr 1 + 2
3
[root@localhost ~]# expr 3 - 1
2
[root@localhost ~]# expr 1 * 3
expr: syntax error
[root@localhost ~]# expr 1 \* 3
3
[root@localhost ~]# expr 9 / 3
3
[root@localhost ~]# expr 10 % 3
1

$? 上一条命令是否执行成功,返回是0,执行成功,返回不是0,执行不成功

[root@localhost ~]# expr 1 + 2.2
expr: non-integer argument
[root@localhost ~]# echo $?
2
[root@localhost ~]# expr 1 + 9
10
[root@localhost ~]# echo $?
0
[root@localhost ~]# expr 1 + 3 &>/dev/null;echo $?
0
[root@localhost ~]# expr 1 + 3.3 &>/dev/null;echo $?
2

bc linux下的计算器(支持浮点运算)

[root@localhost ~]# a=12.3
[root@localhost ~]# b=22.3
[root@localhost ~]# echo "$a+$b" |bc
34.6
[root@localhost ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 

1=1
(standard_in) 2: syntax error
1=1
(standard_in) 3: syntax error
1+1
2
scale=2   小数点后保留两位
2+2.22
4.22

[root@localhost ~]# echo "scale=2;128*100/1819" | bc
7.03

$[] 整数预算

[root@localhost ~]# a=23
[root@localhost ~]# b=32
[root@localhost ~]# echo $[a+b]
55

双小圆括号也可以做运算 (())

[root@localhost ~]# echo $((1+1))
2
[root@localhost ~]# echo $((100+100))
200
[root@localhost ~]# echo $((10000/34))
294

3.6退出脚本

exit NUM 退出脚本,释放系统资源,NUM代表一个整数,代表返回值。

四、SHELL的格式化输出

4.1 echo命令

功能:将内容输出到默认的显示设备。

参数:

​       -n 输出不换行;

​       -e   解释转义字符

​        \n   回车

​        \t    制表符

​       \a    蜂鸣声

**\b 应使用字符之前或之间, 字符尾部跟\b 是没有效果的**
最前面使用 删除后面紧跟的字符,
之间使用删除前一个字符

          [root@localhost ~]# echo -e "\a\a\a\a\a"
          [root@localhost ~]# echo -e "\t\t\t\t hello world"
				 hello world

4.2 SHELL的基本输入 read命令

功能:接受键盘的输入,回车结束。

\#!/usr/bin/bash
clear
#echo -n -e "Login :"
read -p "login" user
#read  user
echo -n -e "Password: "
read -s -t5 -n6 pass
echo ""
echo  -e "$user"
echo  -e "$pass"

-p 打印输出,相当于echo

-s 不显示输出

-t 等待时间

-n 输入长度限制

#!/usr/bin/bash
clear
echo -e "CentOS Linux 7.3 (Core)"
echo -e "Kernel `uname -r` on an `uname -m`\n "
echo -n "localhost login:"
read user
echo -n "Password:"
read -s pass
echo -e "\n"

五、SHELL变量

5.1变量的介绍

在编程中,我们需要把一些临时数据放在内存中,以便后续使用是迅速读出。

5.2变量的类型

1.本地变量,用户私有变量,只有本地用户可以用,保存在本地家目录的.bash_profile .bashrc

系统变量 $HOME,$SHELL,$PWD,$USER 用set命令可以查看系统变量

# .bash_profile

# Get the aliases and functions

if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions

if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

2.全局变量:所有用户都可以使用,保存在 /etc/bashrc /etc/profile

设置环境变量

  export   变量名=变量值     (将shell变量输出位环境变量)

  source   配置文件             (让修改后的配置信息立即生效)

  echo   $变量名                  (查询环境变量的值)

3.用户自定义变量

5.3定义变量

变量名=值

name=xue

中间不能有空格;

变量名不能以数字开头;

不能用标点符号;

不能用关键字;

区分大小写。

反引号将,运行里边的命令,并把结果赋给变量A A=date,这种赋值方法,也可以用 A=$(date)

位置参数变量:

$n (功能描述,n为数字,$0表示命令本身,1-9表示1-9个参数,十以上的要用大括号表示${10},$*表示命令行中的所有参数,把所有的参数看做是一个整体,$@也表示所有参数,把每个参数分开对待

 $#命令行中的参数的个数) 

预定义变量

$$ (当前进程的PID)
$! (后台运行最后一个变量的PID)
$? (最后一个执行命令的返回状态,如果执行正确,返回0,如果返回不是0,则执行不正确)

5.4读取变量

读取变量值,用$符号,引用变量

`[root@localhost ~]# name=xue`
`[root@localhost ~]# NSME=bao`
`[root@localhost ~]# echo $name`
`xue`

5.5取消变量

unset 取消变量

[root@localhost ~]# name=baobao
[root@localhost ~]# echo $name
baobao
[root@localhost ~]# unset name
[root@localhost ~]# echo $name

[root@localhost ~]# 

定义静态变量,不能unset

readonly b=2

5.6定义全局变量

export 定义全局变量

export name=nihao

以上变量都是一次性变量,系统重启后消失。

5.7定义永久变量

本地变量,用户私有变量,只有本地用户可以用,保存在家目录下的 .bash_profile .bashrc

全局变量,所有的用户都可以使用,保存在/etc/profile /etc/bashrc

六 、数组

一个变量可以存多个值。

6.1 数组定义

数组名称=(元素1 元素2 元素3 元素4)

ARY=('a' 'b' 'c' 'd');

6.2数组读出

${数组名称[索引]}

${ARY[2]}

6.3数组赋值

一个赋一个值:

ary[0]='a'

ary[1]='b'

ary[2]='c'

一次赋多个值:

[gis@localhost root]$ ary=(a b c d)
[gis@localhost root]$ echo ${ary[0]}
a
[gis@localhost root]$ echo ${ary[1]}
b
[gis@localhost root]$ echo ${ary[2]}
c

6.4查看数组

[gis@localhost root]$ declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a PIPESTATUS='([0]="0")'
declare -a ary='([0]="a" [1]="b" [2]="c" [3]="d")'

6.5 访问数组

echo ${ary[0]} 访问数组的第一个元素

echo ${ary[@]} 访问数组的所有元素

echo ${#ary[@]} 统计数组中元素的个数

echo ${!ary[@]} 统计数组的索引

echo ${ary[@]:2} 从数组的第二个开始打印

echo ${ary[@]:1:2} 从1开始打印2两个元素

[gis@localhost root]$ echo ${ary[@]}
a b c d
[gis@localhost root]$ echo ${#ary[@]}
4
[gis@localhost root]$ echo ${!ary[@]}
0 1 2 3
[gis@localhost root]$ echo ${ary[@]:2}
c d
[gis@localhost root]$ echo ${ary[@]:2:2}
c d
[gis@localhost root]$ echo ${ary[@]:1:2}
b c
[gis@localhost root]$ echo ${ary[@]:1:3}
b c d
[gis@localhost root]$ echo ${ary[@]:1:4}
b c d

6.6关联数组

关联数组可以允许用户可以自定义数组的索引,使用更高效,方便。

声明一个关联数组

​ declare -A arry1

​ declare -A arry2

关联数组赋值:

挨个赋值 arry1[index1]=a

​ arry1[index2]=b

​ arry1[index3]=c

一次赋多个值 arry=([index1]=a [index2]=b [index3]=c [index4]=d )

[gis@localhost root]$ declare -A arry1
[gis@localhost root]$ arry1=([index1]=a [index2]=b [index3]=c [index4]='hello')
[gis@localhost root]$ declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a PIPESTATUS='([0]="0")'
declare -a ary='([0]="a" [1]="b" [2]="c" [3]="d")'
[gis@localhost root]$ declare -A
declare -A BASH_ALIASES='()'
declare -A BASH_CMDS='()'
declare -A arry1='([index4]="hello" [index1]="a" [index2]="b" [index3]="c" )'
[gis@localhost root]$ 

七、流程控制

7.1SHELL中的运算

数学运算符:

     -eq      等于

    -gt       大于

   -lt          小于

   -ne        不等于

   -ge        大于等于

    -le        小于等于

运算符的几种种写法:

!/bin/bash

RE1=$(((2+3)*4))
echo $RE1

RE2=$[(2+3)*4]
echo $RE2

TEMP=expr 2 + 3
RE3=expr $TEMP \* 4
echo $RE3

[root@localhost ~]# test 1 -eq 2;echo $?
1
[root@localhost ~]# test 1 -eq 1;echo $?
0
[root@localhost ~]# test 3 -gt 2;echo $?
0
[root@localhost ~]# test 4 -lt 5;echo $/
$/
[root@localhost ~]# test 4 -lt 5;echo $?
0
[root@localhost ~]# test 5 -ge 4;echo $?
0

7.2文件比较和运算

-d          文件是否存在且为目录

-e           文件是否存在包括文件和目录

-f             文件是否存在且为文件

-r             文件是否存在且为可读

-s              文件是否存在且不为空

-w             文件是否存在且为可读

-x              文件是否存在且为可执行

-O             文件是否存在且为当前目录所拥有

-G               文件是否存在且为当前用户组所拥有

file1    -nt           file2        比较文件1比文件2新

file1     -ot           file2       比较文件1比文件2旧

7.3字符串比较运算

== 等于

!= 不等于

-n 字符串长度不为0

-z 字符串长度是否为0

7.4逻辑运算

&& 逻辑与

|| 逻辑或

! 逻辑非

7.5 if语句

#!/usr/bin/bash

if [ ! -d /root/abcd ]
     then mkdir -v /root/abcd
     echo "ok"
     echo "yes"
fi
#!/usr/bin/bash

if  [ $USER == root ]
    then
       echo "hello root"
    else
       echo "hello gust"
fi
#!/usr/bin/bash

if [ $1 -gt $2 ]
   then
      echo "$1>$2"
elif [ $1 -eq $2 ]
   then
      echo "$1=$2"
else [ $1 -lt $2 ]
      echo "$1<$2"
fi
~   

(()) 里边可以做数学运算

#!/usr/bin/bash

if (( 100*2>777 ))
   then echo "cuowu"
else
   echo "zhengque"
fi

[[]] 可以做字符匹配

#/usr/bin/bash

for i in ra rb rc cc
  do
    if [[ $i == r* ]]
       then
          echo $i
     fi
done

7.6 for循环

for的第一种写法

seq 用户数字显示 seq -s 横着输出 -w 保持宽度

#!/usr/bin/bash

for i in `seq 1 9`
  do
    echo $i
done
~    

for的第二种写法

#!/usr/bin/bash

for ((i=1;i<10;i++))
   do
      echo $i
done
~    

for多变量

#!/usr/bin/bash

for ((n=0,m=10;n<10;n++,m--))
   do
      echo -e "$n \t $m"
done


7.7循环控制语句 sleep contiue break

sleep N 脚本执行到改地方停止N秒

#!/usr/bin/bash

echo -n "daojishi: "

for i in `seq 9 -1 1`
   do
       echo -n -e "\b$i"
       sleep 1
done

判断服务器是否可以ping通

#!/usr/bin/bash

for ((;;))
      do
        ping -c1 $1 &>/dev/null

      if  [ $? -eq 0 ]
         then
            echo -e "`date +"%F %H:%M:%S"` : $1 is up"
      else
            echo -e "`date +"%F %H:%M:%S"`  : $1 is down"
      fi
    
      sleep 5

done

continue 跳过循环中的某次循环#!/usr/bin/bash**

for ((i=1;i<10;i++))
    do
       if [ $i == 5 ]
          then
             continue
       fi
            echo -e "$i"
done

break 跳出循环执行后续的代码

#!/usr/bin/bash

for ((i=1;i<10;i++))
      do
         echo -e "$i"
      if [  $i == 5 ]
         then
           break
      fi
done
~       
#!/usr/bin/bash

for ((;;))
    do
      read -p "char :" ch
         if [ $ch == "Q" ]
           then
                 break
         else
             echo "$ch"
         fi
done

如果是嵌套循环,break加数字代表跳出循环的层级

#!/usr/bin/bash


for ((i=1;i<10;i++))
      do
         echo "loop $i"

         for((;;))
           do
              echo "nihao"
              break 2       #tiao chu di yi ceng xunhuan
         done

done

7.8打印乘法口诀

#!/usr/bin/bash

for ((i=1;i<10;i++))
     do
        for((j=1;j<10;j++))
           do
              [ $j -le $i ] &&  echo  -n  "$i*$j=` echo -n $(($i*$j))` "
        done
     echo ""
done

7.9 while循环

一般,如果知道循环次数用for,不知道循环次数用while

#!/usr/bin/bash

while read i
      do
         echo "$i"
done < $1
#!/usr/bin/bash

read -p "Login:" account
while [ $account != root ]
   do
       read -p "Login:" account
done

循环嵌套

#!/usr/bin/bash

i=0
while [ $i -lt 10 ]
      do
       i=$(($i+1))
          if [ $i -eq 5 ]
             then
             continue
          fi
       echo "$i"
done

while嵌套for循环实现乘法表

#!/bin/bash

i=1
while [ $i -lt 10 ]
   do
      for ((j=1;j<=$i;j++))
         do
            echo -n -e  "$i*$j= `echo $(($i*$j))`\t"
      done
   echo ""
   i=$(($i+1))
done

while嵌套while实现乘法表

#!/bin/bash

i=1
j=1
while [ $i -lt 10 ]
    do
       j=1
       while [ $j -lt 10 ] && [ $j -le $i ]
          do
              echo -e -n "$i*$j=$(($i*$j))\t"
              j=$(($j+1))
         done
    i=$(($i+1))
    echo ""
done
#!/bin/bash

i=1
j=1
while [ $i -lt 10 ]
    do
       j=1
       while  [ $j -le $i ]
          do
              echo -e -n "$i*$j=$(($i*$j))\t"
              j=$(($j+1))
         done
    i=$(($i+1))
    echo ""
done

7.10 UNTIL循环

#!/usr/bin/bash

num=10
until [ $num -gt 20 ]
        do
        echo $num
        num=$(($num+1))
done

7.11until和while的区别

until是条件测试为假时执行,为真时退出循环。

while是条件测试为真时执行,为假时退出循环。

7.11case多条件分支语句

7.12、SHELL的特殊变量

  1. $* 代表所有参数
  2. $0 脚本名称
  3. $1 第一个参数
  4. $$ 脚本进程号
  5. $_ 脚本最后一个执行的命令

八、函数

常见的函数 basename 用于截取文件名
dirname 用于截取目录文件

8.1、函数的定义

可以用小括号定义函数

#!/usr/bin/bash

#定义函数

start(){
   echo  "Function is start"
}

stop(){
   echo  "Function is stop"
}

#调用函数
start

可以用关键字funciton定义函数

function begin {
   echo  "begin"
}

8.2函数编写实例

#!/usr/bin/bash
function start {
if [  -f /tmp/mysqld.pid.shutdown ]
    then
       systemctl start mysqld
       echo "Mysql is starting"
    else
       echo "Mysql is aleary starting"
 fi
}

function stop {
   if [ -f /tmp/mysqld.pid ]
      then
          systemctl stop mysqld
          echo "Mysql is stopp"
      else
          echo "Mysql is aleard stop"
   fi
}

统计内存使用率

#/bin/bash

function mem(){
     men_used=`head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print(t-f)*100/t}'`
     cache_used=`head -5 /proc/meminfo | awk 'NR==1{t=$2}NR==5{n=$2;print(n*100/t"%")}'`
     buffer_used=`head -4 /proc/meminfo | awk 'NR==1{t=$2}NR==4{m=$2;print(m*100/t"%")}'`
     echo -e "memused: $men_used\tcacheused:$cache_used\tbuffer_used:$buffer_used"
}
    mem

九、正则表达式

9.1正则表达式介绍

正则表达式是一种文本模式匹配,可以用来检查一个字符串是否含有某种子串,将匹配的子串从字符串中替换或者提取出来。

9.2 特殊字符

^ 锚定开头 ^a 以a开头的

$ 锚定结尾 $a 以a结尾的

^ $ 同时使用表示精确匹配,使用一个表示模糊匹配

grep -E 支持正则表达式 等价于 egrep

[root@localhost shell]# egrep ^a file
a
abc
abcd
aaa
[root@localhost shell]# egrep a$ file
a
aaa
ddcca
dada[root@localhost shell]# egrep ^ac$ file
ac

9.3匹配符

匹配符 说明
. 匹配回车以外的任意字符
() 字符串分组
[] 匹配中括号里边的任意字符
[^] 匹配中括号里边的字符取反的字符
\ 转义字符
| a|b a或者b
[root@localhost shell]# egrep ^a[^a-z]c$ file
a2c
a6c
a c
a&c
a c
aDc

[root@localhost shell]# egrep "^(a|b)c$" file    (以a开头或者以b开头的)
bc
ac

9.4限定符

符号 说明
* *出现在这个字母之后表示这个字母可以不出现,或者出现多次
与*号相似,表示该字母可以不出现,或者出现一次
+ 与*号相似,表示该字母出现一次或多次
b{n,m} 表示b最少出现n次,最多出现每次
b{m} 表示b正好出现m次
[root@localhost shell]# egrep "^ab*c$" file  字母b可以不出现也可以出现多次
abc
ac
abc

[root@localhost shell]# egrep "^ac{2,4}b$" file
acccb

9.5 POSIX特殊字符

特殊字符 说明
[:alnum:] 匹配任意字符 a-z A-Z 0-9
[:alpha:] 任意字母大写或者小写
[:digit:] 任意数字
[:upper:] 大写字母
[:alnum:]
[root@localhost shell]# egrep "^a[[:alnum:]]" file
a2c
a6c
abc
abcd
aaa
ac
ab

[root@localhost shell]# egrep "^a[[:digit:]]c$" file
a2c
a6c
[root@localhost shell]# egrep "^a[[:upper:]]c$" file
aDc

9.6匹配 ip地址

方法一:

"^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"

100-199|200-249|250-255|10-99|1-9   #感觉也可以0开头

100-199|200-249|250-255|10-99|0-9

100-199|200-249|250-255|10-99|0-9

100-199|200-249|250-255|10-99|0-9
^((0|1\d?\d?|2(\d?|[0-4]\d|5[0-5])|[3-9]\d?)\.){3}(0|1\d?\d?|2(\d?|[0-4]\d|5[0-5])|[3-9]\d?)$
0的时候后面不能接任何数字
1-199

匹配电话号码:

[root@localhost shell]# egrep "^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$"

十、SHELL对文件的操作

10.1seb命令

一个linux外部命令,流编辑器,非交互式的对文件内容进行增删改查。这是一个行编辑器。

-r 支持正则表达式

a 在后面添加

i 在匹配前添加

p 打印

d 删除

s 查找替换

c 更改

-e 执行多条命令

w 将修改的行写入另外一个文件中

y 转换

-f 指定命令文件

-i 直接把修改写入到文件中

sed -i.bak 's/log/waring/g' data2 先把文件备份然后做修改 .bak 就是自己命名的备份文件

-n 只打印修改过的内容

追加

第三行后面加个 helloworld

[root@localhost shell]# sed '3a\helloworld' data

第2,3,4行后面加个nihao

[root@localhost shell]# sed '2,4a/nihao' data

每一行后面加个hehe

[root@localhost shell]# sed 'a\hehe' data

匹配obso,并在这一行后面加个  zhongguo

[root@localhost shell]# sed '/obso/a\zhongguo' data

行前插入

每一行前面插入用参数   i   

[root@localhost shell]# sed 'i\baishan' data

3-5 行前面插入 banshan

[root@localhost shell]# sed '3,5i\baishan' data

匹配模式

[root@localhost shell]# sed '/debugl/i\baishan' data

删除

删除第三行

[root@localhost shell]# sed '3d\' data

删除2 3 4 行

[root@localhost shell]# sed '2,4d' data

删除匹配

[root@localhost shell]# sed '/install/d' data

删除带#的行

[root@localhost shell]# sed -r '/^#/d' sscon

删除#开头的 ,包含# 的    空行的

[root@localhost shell]# sed -r '/(^#|#|^$)/d' sscon

替换

将ssh替换HHHHHHHHHHHH

[root@localhost shell]# sed 's/ssh/HHHHHHHHH/' sscon 

匹配#  Send 开头的这一行,将environment 替换成GGGGG

[root@localhost shell]# sed '/# Send/s/environment/GGGGGG/' sscon

更改

将第三行改为 hello  world

[root@localhost shell]# sed '3c\hello world'  sscon

将3-20行删除了,加入一行hello world

[root@localhost shell]# sed '3,20c\hello world'  sscon

转换

将abced转换成ABCDE

[root@localhost shell]# sed 'y/abcde/ABCDE/' sscon 

打印

[root@localhost shell]# sed '3,4p' sscon 

sed命令的标志位[root@localhost shell]# sed 's/log/cat/2' data2
log cat logloglog log log
logcat logloglogloglog

将第一个出现的log替换成cat

[root@localhost shell]# cat data2
log log logloglog  log log
loglog logloglogloglog

将第二次出现的log替换成cat

[root@localhost shell]# sed 's/log/cat/' data2
cat log logloglog  log log
catlog logloglogloglog

将所有的都替换

[root@localhost shell]# sed 's/log/cat/g' data2
cat cat catcatcat  cat cat
catcat catcatcatcatcat

把替换的行写入另外一个文件

[root@localhost shell]# sed 's/log/cat/w data3' data2


加  -n  参数  打印修改的过的内容

[root@localhost shell]# sed -n 's/log/cat/p' data2
catloglog  loglog  log
catlog log  log log  log
catlog*log 0 log 000log
3catlog

参数 -e 可以加多个条件

[root@localhost shell]# sed -e 's/log/cat/;s/var/long/' data2
catloglog  loglog  log
catlog log  log log  log
catlog*log 0 log 000log
3catlog long  varvarvar
long   varvar  varvar varvar
longvar  varvar

参数 f 可以执行预先写好的文件

vi   data4

s/log/cat/
s/var/HHHH/

[root@localhost shell]# sed -f data4 data2
catloglog  loglog  log
catlog log  log log  log
catlog*log 0 log 000log
3catlog HHHH  varvarvar
HHHH   varvar  varvar varvar
HHHHvar  varvar

10.2 sed小技巧

1.统计行号

[root@localhost shell]# sed -n '$=' data
1

十一、输出流的处理

[root@localhost ~]# head -3 /proc/meminfo
MemTotal:        1863104 kB
MemFree:         1594984 kB
MemAvailable:    1579180 kB

11.1 awk数据列提取功能

1.对列的截取

$0 整个文本

$1 第一列

$2 第二列

$N 第N列

$NF 最后一列

-v 指定变量

1.打印整个文本

  1. [root@localhost shell]# awk '{print $0}' awkst
    
    1. Have a nice day. 
    
    2. So far, so good. 
    
    3. Take it or leave it.
    
    4. Keep it up! 
    
    5. Good for you. 
    
    6. Time flies!
    

    2.打印最后一列

    [root@localhost shell]# awk '{print $NF}' awkst
    day.
    
    good.
    
    it.
    
    up!
    
    you.
    
    flies!
    

    3.打印第三列

    
    [root@localhost shell]# awk '{print $3}' awkst 
    a
    
    far,
    
    it
    
    it
    
    for
    
    flies!
    

11.2 提取行

用特殊字符限定 NR 用==

打印第三行

[root@localhost shell]# awk 'NR==3{print $0}' awkst 

​      2.  So far, so good. 

11.3 用 -F 指定 列的分隔符

打印指定行,并且打印多列

[root@localhost shell]# awk -F ":" 'NR==3 {print $2,$5,$7}' passwd 
x daemon /sbin/nologin

打印指定的行,并且打印多列,并且加连接符

[root@localhost shell]# awk -F ":"  'NR==4 {print $2 "-" $5 "-" $7}' passwd
x-adm-/sbin/nologin
[root@localhost shell]# awk -F ":" 'NR==1 {print "account: "$1,"UID: " $3,"DESC:" $5}' passwd
account: root UID: 0 DESC:root

11.4 awk程序执行的优先级

begin最高,其次是program ,最后是end

begin 是处理数据流之前要干的事情。

program 处理数据流

end 处理完数据流要干的事情

[root@localhost shell]# awk 'BEGIN{print "hello world"}{print $1}END{print "hello tomorrow"}' awkst 
hello world
1.

2.

3.

4.

5.

6.

hello tomorrow

11.5 awk 高级用法

赋值

[root@localhost shell]# head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{n=$2;print(t-n)*100/t "%"}'
14.5276%
[root@localhost shell]# awk 'BEGIN{name="hello"; print name}'
hello
[root@localhost shell]# awk 'BEGIN{arrary[1]="hello";arrary[2]=13;print arrary[1];print arrary[2]}'
hello
13

11.6 awk的运算

比较运算

[root@localhost shell]# seq 1 9 > num
[root@localhost shell]# cat num
1
2
3
4
5
6
7
8
9
[root@localhost shell]# awk '$1>5{print $0}' num
6
7
8
9

数学运算

[root@localhost shell]# awk 'BEGIN{print 1*4}'
4

逻辑运算

[root@localhost shell]# awk 'BEGIN{ print 100>=4 && 4>=3 }'
1

++运算

[root@localhost shell]# awk -v 'count=100' 'BEGIN{count++;print count}'
101

匹配

精确匹配

[root@localhost shell]# awk -F: '$1=="root"{print $0}' passwd 

root:x:0:0:root:/root:/bin/bash

精确不匹配


[root@localhost shell]# awk -F: '$1!="root"{print $0}' passwd

模糊匹配

[root@localhost shell]# awk -F: '$1 ~ "ro"{print $0}' passwd 
root:x:0:0:root:/root:/bin/bash

模糊不匹配

[root@localhost shell]# awk -F: '$1 !~ "ro"{print $0}' passwd 

嵌套循环

[root@localhost shell]# awk '{if($1>5)print $0}' num
6
7
8
9
[root@localhost shell]# awk '{if($1>5) print $1*2;else print $1/2}' num
0.5
1
1.5
2
2.5
12
14
16
18

11.7 awk小技巧

统计行号

[root@localhost shell]# awk 'END{print NR}' num
9

打印最后一行

[root@localhost shell]# awk 'END{print $0}' passwd 
mysql:x:998:996::/home/mysql:/sbin/nologin

统计有多少列

[root@localhost shell]# awk -F: 'END{print NF}' passwd 
7

十二、实战

判断主机网络是否通

#!/usr/bin/bash

memory(){
temp_file=`mktemp toptt.XXX`


top -b -n 1 > $temp_file

tail -n +8 $temp_file | awk '{arrary[$NF]=$6}END{for (i in arrary) print arrary[i],i}' |sort -k 1 -n -r | head -10

rm -rf $temp_file

}

cpu() {

temp_file=`mktemp toptt.XXX`

top -b -n 1 > $temp_file

tail -n +8 $temp_file | awk '{arrary[$NF]=$9}END{for (i in arrary) print arrary[i],i}' |sort -k 1 -n -r | head -10

rm -rf $temp_file
}

\#!/usr/bin/bash

temp_file=`mktemp toptt.XXX`


top -b -n 1 > $temp_file

tail -n +8 $temp_file | awk '{arrary[$NF]+=$6}END{for (i in arrary) print arrary[i],i}' |sort -k 1 -n -r | head -10

十三、SHELL使用总结

13.1引号的用法总结

​ " " 除了 $ \ ` " 都是是普通字符

​ ` ` shell命令

​ ' ' 普通字符

posted @ 2021-11-20 12:12  中仕  阅读(4)  评论(0编辑  收藏  举报