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
-
bash 1.sh
-
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的特殊变量
- $* 代表所有参数
- $0 脚本名称
- $1 第一个参数
- $$ 脚本进程号
- $_ 脚本最后一个执行的命令
八、函数
常见的函数 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.打印整个文本
-
[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命令
' ' 普通字符