目录
一、字符处理
cut命令
awk命令
sed命令
字符串排序
二、条件判断
文件类型判断
文件权限判断
两个文件的判断
整数比较
字符串判断
多重判断
三、流程控制
if分支
if else 双分支结构
case分支
for循环
while循环
一、字符处理
cut命令
命令格式: cut [选项] 文件名
选项:
-f 列号: 提取第几列
-d 分隔符: 按照指定分割符进行分割,默认的分割符是制表符,注意分割符不能使用空格。
示例:
# 每个字段已制表符分割,不能是空格。
[root@localhost ~]# vi person.txt
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
[root@localhost ~]# cut -f 2 person.txt
Name
ls
zs
ww
[root@localhost ~]# cut -f 2,3 person.txt
Name sex
ls m
zs m
ww w
# 指定分割符的示例
[root@localhost ~]# cut -d ":" -f 1,3 /etc/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
...
# 在管道符中使用的例子
[root@localhost ~]# cat /etc/passwd | cut -d ":" -f 1,3
root:0
bin:1
daemon:2
...
# cut的局限性,提取第五列没有作用,因为分隔符是连续的空格,而不是制表符
[root@localhost ~]# df -h | cut -f 5
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 475M 0 475M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.7M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.7G 16G 10% /
/dev/sda1 1014M 167M 848M 17% /boot
tmpfs 98M 0 98M 0% /run/user/0
[root@localhost ~]#
# 指定分隔符为空格符也不行,因为不知道到底又几个空格
[root@localhost ~]# df -h | cut -d " " -f 5
awk命令
格式化输出命令:
printf '输出类型输出格式' 输出内容
输出类型:
- %ns 输出字符串,n表示输出几个字符
- %ni 输出整数,n表示输出几个数字
-
%m.nf 输出浮点数, m 表示输出的总位数, n 表示小数点的位数
输出格式:
-
\a 输出警告音
-
\b 输出退格键
-
\f 清除屏幕
-
\n 换行
-
\r 回车
-
\t 水平方向 tab
-
\v 垂直方向 tab
[root@localhost ~]# printf %s 1 2 3 4 5
12345[root@localhost ~]#
# 下面的写法不可以,需要用单引号将类型说明引起来,下面又正确的示例
[root@localhost ~]# printf %s %s %s 1 2 3 4 5 6
%s%s123456[root@localhost ~]#
# 1 2 3 最为一组字符的,4 5 6作为一组, 中间没有换行
[root@localhost ~]# printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6[root@localhost ~]#
# 输出一组后加一个换行
[root@localhost ~]# printf '%s %s %s\n' 1 2 3 4 5 6
1 2 3
4 5 6
# printf不能和管道符一起使用,如果需要从文件中获取,则可以如下写法:
[root@localhost ~]# printf '%s' $(cat person.txt)
IDNamesexage1lsm182zsm253www22[root@localhost ~]#
# 这样就可以了
[root@localhost ~]# printf '%s\t %s\t %s\t %s\n' $(cat person.txt)
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
# printf经常与awk一起使用
awk命令格式:
awk '
条件
1 {
动作
1}
条件
2{
动作
2} ...'
文件名
条件:
一般使用关系表达式作为条件
x > 0 x >= 0
x <= 0
动作:
格式化输出,如
printf
流程控制语句
示例:
# 没有指定条件,即输出所有行,动作是使用printf进行格式化输出
[root@localhost ~]# awk '{printf $2 "\t" $4 "\n"}' person.txt
Name age
ls 18
zs 25
ww 22
# print会在行末自动加换行符
[root@localhost ~]# df -h | awk '{print $1 "\t" $5 "\t" $6}'
文件系统 已用% 挂载点
devtmpfs 0% /dev
tmpfs 0% /dev/shm
tmpfs 2% /run
tmpfs 0% /sys/fs/cgroup
/dev/mapper/centos-root 10% /
/dev/sda1 17% /boot
tmpfs 0% /run/user/0
# 使用管道符将多个命令组合使用
[root@localhost ~]# df -h | grep sda1 | awk '{print $5}' | cut -d "%" -f 1
17
# 指定分割符
[root@localhost ~]# awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
#第一行格式不符合要求,
bin 1
daemon 2
adm 3
# 使用begin在读入第一行之前是设置分割符生效
[root@localhost ~]# awk 'BEGIN{FS=":"} {print $1 "\t" $3}' /etc/passwd
root 0
bin 1
daemon 2
# 在输出之前先设置分割符,在输出完后提示一个end
[root@localhost ~]# awk 'BEGIN{FS=":"} END{print "end"} {print $1 "\t" $4}'
/etc/passwd
root 0
bin 1
daemon 2
adm 4
...
end
# 首选读取person文件数据,并传给awk命令,awk命令选取第四列大于等于20的数据(年龄),
# 并格式化输出第二列(名字)
[root@localhost ~]# cat person.txt | awk '$4 >= 20 {print $2 }'
Name
zs
ww
sed命令
适合所有的
Unix
及
linux
平台的轻量级的流编辑器,可以对数据进行选取,替换,删除,新增等操作。
注意:
vim
也可以编辑文件,但是不能用来修改命令结果中的内容,如使用管道符将前一个命令的结果
传给
vim
进行处理,这一点
vim
做不到。
命令格式:
sed [
选项
] '[
动作
]'
文件名
选项:
-n
:
sed
命令会把所用的数据输出到屏幕,使用该选项则只会将
sed
命令处理的行输出到屏幕
-e
: 允许对输入数据应用多条
sed
命令编辑
-i
:
把
sed
的修改结果同步到数据文件中去,而不是屏幕。
动作:
a\:
追加,在当前行后面追加一行或多行
c\:
行替换,用
c
之后的字符串替换原来的数据,替换多行时,除最后一行外,每行需要用
""
表示数据未
完结
i\:
插入,在当前行之前插入一行或多行,插入多行时,除最后一行外,每行需要用
""
表示数据未完结
d:
删除指定的行
p:
打印,输出指定的行
s:
字符串替换,格式为:
“
行范围
s/
需要替换的字符
/
替换的新字符
/g”
# 2p 代表输出第二行,输出后又会将其他行输出,这是sed的默认行为,如果不想输出其他行
# 则需要使用n参数
[root@localhost ~]# sed '2p' person.txt
ID Name sex age
1 ls m 18
1 ls m 18
2 zs m 25
3 ww w 22
[root@localhost ~]# sed '2p' -n person.txt
1 ls m 18
# 和管道符结合的示例
[root@localhost ~]# cat person.txt | sed '2p' -n
1 ls m 18
# 删除2,3行数据,注意只是在结果中删除,不会在文件中删除,可以使用cat命令进行验证
[root@localhost ~]# sed '2,3d' person.txt
ID Name sex age
3 ww w 22
[root@localhost ~]# cat person.txt
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
# 追加数据,同样不会影响源文件,因为没有使用-i参数
[root@localhost ~]# sed '4a 4\ttq \tn\t23' person.txt
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
4 tq n 23
# 替换第四行(行替换),不会影响原文件
[root@localhost ~]# sed '4c tihuan' person.txt
ID Name sex age
1 ls m 18
2 zs m 25
tihuan
# 指定字符串替换,不会影响原文件
[root@localhost ~]# sed "3s/25/52/g" person.txt
ID Name sex age
1 ls m 18
2 zs m 52
3 ww w 22
# 这下把文件也替换了
[root@localhost ~]# sed -i "3s/25/52/g" person.txt
[root@localhost ~]# cat person.txt
ID Name sex age
1 ls m 18
2 zs m 52
3 ww w 22
字符串排序
命令格式:
sort [
选项
]
文件名
选项:
-f
忽略大小写
-n
数值型排序
-r
反向排序
-t
指定分割符,默认为制表符
-k n[,m]
用指定的字段范围排序, 如果不指定
m
,则表示从
n
到行尾。
[root@localhost ~]# sort /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
[root@localhost ~]# sort -r /etc/passwd
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
...
# 对passwd文件,使用”:”作为分割符,去第三个字段进行排序,
# 在排序时将第三字段作为数字(不指定-n则默认作为字符排序)
# 上述的作用即:使用uid数字对passwd文件进行排序
[root@localhost ~]# sort -n -t":" -k 3,3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
统计命令
wc
命令格式:
wc [
选项
]
文件名
选项:
-l
只统计行数
-w
只统计单词数
-m
只统计单词数
[root@localhost ~]# wc person.txt
4 16 46 person.txt
# 文件有4行,16单词,46个字符
[root@localhost ~]# wc -l person.txt
4 person.txt
# 文件有4行
二、条件判断
文件类型判断
-d |
判断指定的目录是否存在
|
-e |
判断文件是否存在,存在即为真
|
-f |
判断普通文件是否存在
|
-L |
判断文件是否存在且为连接文件
|
示例:
# 判断文件是否存在,存在为0, 不存在为1
[root@localhost ~]# test -e person.txt
[root@localhost ~]# echo $?
0
[root@localhost ~]#
[root@localhost ~]# test -e aba
[root@localhost ~]# echo $?
1
# 出test外,可以使用中括号
[root@localhost ~]# [ -e person.txt ]
[root@localhost ~]# echo $?
0
[root@localhost ~]#
[root@localhost ~]# [ -d /home ] && echo "is directory" || "is not directory"
is directory
[root@localhost ~]# [ -f ./person.txt ] && echo "yes" || echo "no"
yes
文件权限判断
-r |
判断文件是否存在且有读权限
|
-w |
判断文件是否存在且有写权限
|
-x |
判断文件是否存在且有执行权限,注意:拥有者,所属组,其他人只用有一个有指定权限就
会返回真,上面的参数也一样
|
-u |
判断文件是否存在且有
SUID
权限
|
-g |
判断文件是否存在且有
SGID
权限
|
-k |
判断文件是否存在且有
SBIT
权限
|
[root@localhost ~]# [ -r ./person.txt ] && echo "yes" || echo "no"
yes
两个文件的判断
file1 -nt file2
|
file1
的最后修改时间是否比
file2
新,是在返回真
|
file1 -ot file2
|
file1
的最后修改时间是否比
file2
旧,是在返回真
|
file1 -ef file2
|
file1
的
inode
号是否与
file2
的一致,即是否为同一个文件
|
[root@localhost ~]# touch abc.txt
[root@localhost ~]# [ person.txt -nt abc.txt ] && echo "yes" || echo "no"
no
整数比较
num1 -eq num2
| == |
num1 -ne num2
| != |
num1 -gt num2
| > |
num1 -lt num2
| < |
num1 -ge num2
| >= |
num1 -le num2
| <= |
[root@localhost ~]# [ 1 -gt 2 ] && echo "yes" || echo "no"
no
字符串判断
-z str
|
是否为空,为空返回真
|
-n str
|
判断是否为非空,非空返回真
|
str1 == str2
|
判断是否相等
|
str1 != str2
|
判断是否不等
|
示例:
[root@localhost ~]# name=zs
[root@localhost ~]# [ -z "$name" ] && echo "yes" || echo "no"
no
[root@localhost ~]# [ "abc" == "bcd" ] && echo "yes" || echo "no"
no
[root@localhost ~]# [ "abc" == "abc" ] && echo "yes" || echo "no"
yes
多重判断
判断
1 -a
判断
2
|
and
|
判断
1 -o
判断
2
| or |
!
判断
| 非 |
示例:
[root@localhost ~]# num=100
# 判断num是否存在,且大于200
[root@localhost ~]# [ -n "$num" -a "$num" -gt 200 ] && echo "yes" || echo "no"
no
[root@localhost ~]# num=201
# 判断num是否存在,且大于200
[root@localhost ~]# [ -n "$num" -a "$num" -gt 200 ] && echo "yes" || echo "no"
yes
三、流程控制
if分支
if [ condition ]; then语句fi或者if [ condition ]then语句fi
示例1:
[root@localhost ~]# vim iftest.sh
#!/bin/bash
#author:test
num=$1
if [ $num -ge 100 ];then
echo ">100"
fi
[root@localhost ~]# vim iftest.sh
#!/bin/bash
#author:test
num=$1
if [ $num -ge 100 ];then
echo ">100"
fi
[root@localhost ~]# chmod 777 iftest.sh
[root@localhost ~]# ./iftest.sh 102
>100
示例
2
:
#!/bin/bash
# author: tt
# description: 当sda1盘的占用到90%即输出警告信息
rate=$(df -h | grep "/dev/sda1" | awk '{print $5}' | cut -d "%" -f 1)
if [ $rate -ge 90 ]
then
echo "Warning ! /dev/sda1 is full"
fi
if else 双分支结构
if [ condition ]then语句elif [ condition ]; then语句else语句fi
示例1:
[root@localhost ~]# vim iftest02.sh
#!/bin/bash
#author:tt
num=$1
if [ $num -gt 100 ]
then
echo "num > 100"
else
echo "num <= 100"
fi
[root@localhost ~]# chmod 755 iftest02.sh
[root@localhost ~]# ./iftest02.sh 200
num > 100
示例
2
:
[root@localhost ~]# vim iftest03.sh
#!/bin/bash
read -p "please input a num:" num
if [ $num -gt 10 -a $num -le 100 ]
then
echo "100>=num>10"
exit 1
elif [ $num -gt 100 -a $num -le 1000 ]; then
echo "1000>=num>100"
exit 2
elif [ $num -gt 1000 -a $num -le 10000 ]; then
echo "10000>=num>1000"
exit 3
else
echo "other num"
fi
[root@localhost ~]# chmod 755 iftest03.sh
[root@localhost ~]# ./iftest03.sh
please input a num:1000
1000>=num>100
[root@localhost ~]#
case分支
与 if elif else 语句一样都是属于分支语句,不同点在于, case 只能判断一种条件关系, if 可以判断多种条件关系。case 语法:case $conditionVar in"val1" ) # 注意此处只能有一个条件,不能像 if 那样使用复杂的多条件若值为 val1 ,则执行这里;;"val2")若值为 val1 ,则执行这里;;...*)其他变量值则执行这里;;esac
示例:
[root@localhost ~]# vim casetest.sh
#!/bin/bash
# author: tt
# discription: 演示case语法
read -p "please input y/n " -t 30 inchoose
case $inchoose in
"y")
echo "your input is y"
;;
"n")
echo "your input is n"
;;
*)
echo "your input is others "
;;
esac
[root@localhost ~]# chmod 755 casetest.sh
[root@localhost ~]# ./casetest.sh
please input y/n y
your input is y
for循环
1
) 用法一
for
变量
in
值
1
值
2
值
3
值
4 ...
do
执行语句
done
示例
1
:
[root@localhost ~]# vim fortest.sh
#!/bin/bash
# author: tt
# description: for demo
for i in 1 2 3 4 5 6
do
echo $i
done
[root@localhost ~]# chmod 755 fortest.sh
[root@localhost ~]# ./fortest.sh
...
示例
2
:
[root@localhost ~]# vim fortest2.sh
#!/bin/bash
for ((i=1;i<=100;i++));
do
echo $((i));
done
示例
3
:
[root@localhost ~]# vim fortest3.sh
#!/bin/bash
for i in $(seq 1 50)
do
echo $(expr $i)
done
示例
4
:
[root@localhost ~]# vim fortest4.sh
#/bin/bash
for i in {1..50}
do
echo $((i));
done
示例
5
:
[root@localhost ~]# vim fortest5.sh
#/bin/bash
list="hello shell word";
for str in $list
do
echo $str
done
示例
6:
[root@localhost ~]# vim fortest6.sh
#/bin/bash
for f in /tmp/*;
do
echo $f;
done
while循环
只要满足循环条件则进行循环
格式:
while [ 条件判断 ]do语句done
示例:
[root@localhost ~]# vim whiletest1.sh
#!/bin/bash
i=1
s=0
while [ $i -le 100 ]
do
s=$((s+i));
i=$((i+1));
done
echo "sum = $s"
until
循环
只有条件满足才退出循环
格式:
until [
条件
]
do
语句
done
示例:
[root@localhost ~]# vim untiltest.sh
#/bin/bash
i=0
s=0
until [ $i -gt 100 ]
do
s=$((s+i));
i=$((i+1));
done
echo "sum = $s"