这里是一段防爬虫文本,请读者忽略。
本文原创首发于CSDN,作者IDYS
博客首页:https://blog.csdn.net/weixin_41633902/
本文链接:https://blog.csdn.net/weixin_41633902/article/details/108453404
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!
Shell
当中适用,因为用来在文件当中搜索字符串的命令,如grep
、awk
、sed
等命令可以支持正则表达式,而在系统当中搜索文件的命令,如 ls
、find
、cp
这些命令不支持正则表达式,所以只能使用 shell
自己的通配符来进行匹 配了。元字符 | 作用 |
---|---|
* |
前一个字符匹配0 次或任意多次 |
. |
匹配除了换行符外任意一个字符 |
^ |
匹配行首。例如:^hello 会匹配以 hello 开头的行 |
$ |
匹配行尾。例如:hello&会匹配以 hello 结尾的行 |
[^] |
匹配除中括号的字符以外的任意一个字符。例如:[^0-9] 匹配任意 一位非数字字符,[^a-z] 表示任意一位非小写字母。 |
\ |
转义符。用于取消。将特殊符号的含义取消。 |
\{n\} |
表示其前面的字符恰好出现 n 次。例如:[0-9]\{4\} 匹配 4 位数字, [1][3-8][0-9]\{9\} 匹配手机号码。 |
\{n,\} |
表示其前面的字符出现不小于 n 次。例如: [0-9]\{2,\} 表示两位及以上的数字。 |
\{n,m\} |
表示其前面的字符至少出现n 次,最多出现m 次。例如:[a-z]\{6,8\} 匹配 6 到 8 位的小写字母。 |
Linux
中正则表达式分为基础正则表达式和扩展正则表达式,grep
只支持基础正则表达式,grep -E
支持扩展正则表达式,egrep
支持扩展正则表达式grep
可以显示颜色[root@idys1 ~]# vim ~/.bashrc
alias grep='grep --color=auto'
[root@idys1 ~]# source .bashrc # 使其生效
# 为了演示方便,我修改命令提示符变量 PS1
[root@idys1 ~]# echo $PS1
[\u@\h \W]\$
[root@idys1 ~]# vim /etc/profile
[root@idys1 ~]# source /etc/profile
your UID=0 your home=/root
[dayuanshuai@idys1 day5] vim my_task_file.txt
1 Mr. Li idys said:
2 he was the most honest man.
3 123despise him.
4 But since Mr. linus towards came,
5 he never saaaid those words.
6 5555nice!
7 because,actuaaaally,
8 Mr. idys Linus is the most honest man
9 Later,Mr. Li idys soid his hot body
10 and every think it is so fun.
11 there is worthy to see
*
前一个字符匹配 0
次,或任意多次a
的行[dayuanshuai@idys1 day5] grep a my_task_file.txt
Mr. Li idys said:
he was the most honest man.
But since Mr. linus towards came,
he never saaaid those words.
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
s
与id
之间至少有两个a
的行[dayuanshuai@idys1 day5] grep 'sa\{2,\}id' my_task_file.txt
he never saaaid those words.
no one saaid he is honest
# 以下也可以
[dayuanshuai@idys1 day5] grep saaa*id my_task_file.txt
he never saaaid those words.
no one saaid he is honest
.
匹配除了换行符外任意一个字符.
只能匹配一个字符,这个字符可以是任意字符[dayuanshuai@idys1 day5] grep s..d my_task_file.txt
Mr. Li idys said:
Later,Mr. Li idys soid his hot body
通配符中
*
代表任意的长度的所有字符,?
代表单个字符
[dayuanshuai@idys1 day5] grep ".*" my_task_file.txt
Mr. Li idys said:
he was the most honest man.
123despise him.
But since Mr. linus towards came,
he never saaaid those words.
5555nice!
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
^
匹配行首,$
匹配行尾M
开头的行[dayuanshuai@idys1 day5] grep "^M" my_task_file.txt
Mr. Li idys said:
Mr. idys Linus is the most honest man
n
结尾的行[dayuanshuai@idys1 day5] grep "n$" my_task_file.txt
Mr. idys Linus is the most honest man
[dayuanshuai@idys1 day5] cat my_task_file.txt
Mr. Li idys said:
he was the most honest man.
123despise him.
But since Mr. linus towards came,
he never saaaid those words.
5555nice!
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
22222
1111
03423
[dayuanshuai@idys1 day5] sed -r 's/^[[:space:]]+//g' my_task_file.txt
Mr. Li idys said:
he was the most honest man.
123despise him.
But since Mr. linus towards came,
he never saaaid those words.
5555nice!
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
22222
1111
03423
#
和空格[dayuanshuai@idys1 day5] cat my_task_file.txt
Mr. Li idys said:
he was the most honest man.
123despise him.
But since Mr. linus towards came,
he never saaaid those words.
5555nice!
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
22222
1111
03423
# dwdsd
# awda
# # # sefr
[dayuanshuai@idys1 day5] sed -r "s/^[#,[:space:]]+//g" my_task_file.txt
Mr. Li idys said:
he was the most honest man.
123despise him.
But since Mr. linus towards came,
he never saaaid those words.
5555nice!
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
22222
1111
03423
dwdsd
awda
sefr
[dayuanshuai@idys1 day5] grep -n '^$' my_task_file.txt
19:
20:
grep -v
表示对匹配到的字符取反,查找非空白行,(含有空格的行,也为空白行)[dayuanshuai@idys1 day5] cat -n my_task_file.txt
1 Mr. Li idys said:
2 he was the most honest man.
3 123despise him.
4 But since Mr. linus towards came,
5 he never saaaid those words.
6 5555nice!
7 because,actuaaaally,
8 no one saaid he is honest
9 Mr. idys Linus is the most honest man
10 Later,Mr. Li idys soid his hot body
11 and every think it is so fun.
12 there is worthy to see
13 22222
14 1111
15 03423
16 # dwdsd
17 # awda
18 # # # sefr
19
20
21
22
23 lll
[dayuanshuai@idys1 day5] grep -nv "^[[:space:]]*$" my_task_file.txt
1:Mr. Li idys said:
2:he was the most honest man.
3:123despise him.
4:But since Mr. linus towards came,
5:he never saaaid those words.
6:5555nice!
7:because,actuaaaally,
8:no one saaid he is honest
9:Mr. idys Linus is the most honest man
10:Later,Mr. Li idys soid his hot body
11:and every think it is so fun.
12:there is worthy to see
13: 22222
14: 1111
15: 03423
16:# dwdsd
17:# awda
18:# # # sefr
23:lll
.
不会匹配空白行,但是会匹配空格
[]
匹配中括号中指定的任意一个字符,只匹配一个字符[]
会匹配中括号中指定任意一个字符,注意只能匹配一个字符。比如[ao]
中要么会匹配一个 a
字符,要不会匹配一个 o
字符:[dayuanshuai@idys1 day5] grep "s[ao]id" my_task_file.txt
Mr. Li idys said:
Later,Mr. Li idys soid his hot body
[ao]
后面加入*
号呢?那么它就会变为0
个到任意个a
和o
的组合方式[dayuanshuai@idys1 day5] grep "s[ao]*id" my_task_file.txt
Mr. Li idys said:
he never saaaid those words.
no one saaid he is honest
Later,Mr. Li idys soid his hot body
saoid
soaid
soooid
saaaid
saooaoaid
sid # 即使s 和 id中,没有任意一个字符也会匹配
[^]
匹配除中括号的字符以外的任意一个字符[dayuanshuai@idys1 day5] grep -E "^[[:digit:][:space:]]*$" my_task_file.txt
22222
1111
03423
[dayuanshuai@idys1 day5] grep "^[^0-9]*$" my_task_file.txt
Mr. Li idys said:
he was the most honest man.
But since Mr. linus towards came,
he never saaaid those words.
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
saaaoooaoao
saoid
soaid
soooid
saaaid
saooaoaid
sid
# dwdsd
# awda
# # # sefr
lll
[dayuanshuai@idys1 day5] cat my_task_file.txt
Mr. Li idys said:
he was the most honest man.
123despise him.
But since Mr. linus towards came,
he never saaaid those words.
5555nice!
because,actuaaaally,
no one saaid he is honest
Mr. idys Linus is the most honest man
Later,Mr. Li idys soid his hot body
and every think it is so fun.
there is worthy to see
saaaoooaoao
saoid
soaid
soooid
saaaid
saooaoaid
sid
22222
1111
03423
# dwdsd
# awda
# # # sefr
123
lll
123
[dayuanshuai@idys1 day5] grep -nE '^[^a-z]+$' my_task_file.txt | grep -vE "[[:space:]]+"
31:123
\
转义符.
结尾的行[dayuanshuai@idys1 day5] grep "\.$" my_task_file.txt
he was the most honest man.
123despise him.
he never saaaid those words.
and every think it is so fun.
3
个连续的数字,不能匹配[dayuanshuai@idys1 day5] grep "[[:digit:]]\{3\}[^[:digit:]]" my_task_file.txt
123despise him.
5555nice!
123
\{n\}
表示其前面的字符恰好出现 n
次3
个a的行,中间多一个a
也不行[dayuanshuai@idys1 day5] grep 'a\{3\}' my_task_file.txt
# 按照这种方式就会看到4个连续a的情况
he never saaaid those words.
because,actuaaaally, # 含有4个连续的a
saaaoooaoao
saaaid
[dayuanshuai@idys1 day5] grep '[^a]a\{3\}[^a]'
# 这种方式的话就会看到只含有3个连续a的情况,多一个a也不符合
my_task_file.txt
he never saaaid those words.
saaaoooaoao
saaaid
4
个连续的a
或者4
个以上连续的a的行[dayuanshuai@idys1 day5] grep 'a\{4,\}' my_task_file.txt
because,actuaaaally,
3
个数字过滤出来显示。连续数字超过3个的则不显示# 先过滤出 只含有三个连续数字的行
[dayuanshuai@idys1 day5] grep -E "[^[:digit:]][[:digit:]]{3}[^[:digit:]]|^[[:digit:]]{3}[^[:digit:]]|[^[:digit:]][[:digit:]]{3}$" my_task_file.txt
123despise him.
my123dddand456dd
123
# 然后再将3个数字提炼出来
[dayuanshuai@idys1 day5] grep -E "[^[:digit:]][[:digit:]]{3}[^[:digit:]]|^[[:digit:]]{3}[^[:digit:]]|[^[:digit:]][[:digit:]]{3}$" my_task_file.txt | grep -oE '[[:digit:]]{3}'
123
123
456
123
\{n,\}
表示其前面的字符出现不小于 n
次3
次及其以上的数字[dayuanshuai@idys1 day5] grep -o "[[:digit:]]\{3,\}" my_task_file.txt
123
5555
123
456
22222
1111
03423
123
123
\{n,m\}
匹配其前面的字符至少出现 n
次,最多出现 m
次[dayuanshuai@idys1 day5] grep -o "[[:digit:]]\{2,3\}" my_task_file.txt
123
555
123
456
222
22
111
034
23
123
123
正则表达式中还可以支持一些元字符,比如+
,?
,|
,()
其实 Linux
是支持这些元字符的,只是 grep
命令默认不支持而已。如果要想支持这些元字符,必须使用 egrep
命令或 grep -E
选项,所以我们又把这些元字符称作扩展元字符。
如果查询 grep
的帮助,对 egrep
的说明就是和 grep -E
选项一样的命令,所以我们可以把两个命令当做别名来对待
扩展元字符 | 作用 |
---|---|
+ |
前一个字符匹配 1 次或任意多次。 如“go+gle ”会匹配gogle 、google 或gooogle ,当然如果o 有更多个,也能匹配。 |
? |
前一个字符匹配 0 次或 1 次。如colou?r 可以匹配colour 或color 。 |
| |
匹配两个或多个分支选择。 如was|his 会匹配既包含was 的行,也匹配包含his 的行 |
() |
匹配其整体为一个字符,即模式单元。可以理解为由多个单个字符组成的大字符。 如“(dog)+”会匹配dog 、dogdog 、dogdogdog 等,因为被() 包含的字符会当成一个整体。但hello (world | earth) 会匹配hello world 及hello earth 。 |
[dayuanshuai@idys1 day5] cat email.txt
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[dayuanshuai@idys1 day5] grep -E "[[:alnum:]]+@[[:alnum:]]+\.com$" email.txt
[email protected]
[email protected]
IP
地址,非法IP
地址不匹配[dayuanshuai@idys1 day5] cat new_ip.txt
123.45.12.123wq
q123.12.1.1c
1233.1234.1.12c
12.12.123.12
1.1.2.3
12.1.212.1.5
1.0.0.0
0.0.0.0
127.12.0.0
12.12.124.123.231.123
192.168.1.0
[dayuanshuai@idys1 day5] grep -Eo "^((\b[1-9]\b|\b[1-9][0-9]\b|\b1[0-9]{2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){1}((\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){2}(\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{2}\b|\b2[0-4][0-9]\b|\b25[0-4]\b){1}$" new_ip.txt | grep -vE "[[:digit:]]+.0.0.0|[[:digit:]]+.[[:digit:]]+.0.0"
12.12.123.12
192.168.1.0
cut
列提取命令cut
[选项] 文件名-f
列号:提取第几列-d
分隔符:按照指定分隔符分割列-c
字符范围:不依赖分隔符来区分列,而是通过字符范(行首为 0)来进行字段提取。n-
表示从第 n 个字符到行尾;n-m
从第 n
个字符到第 m
个字符;-m
表示从第 1
个字符到第m 个字符。cut 命令的默认分隔符是制表符,也就是
tab
键,不过对空格符可是支持的不怎么好啊。我们先建立一个测试文件,然后看看cut命令的作用吧:
TAB
# 首先 创造一个文本,这个时候,字符的显示格式是不对齐
[dayuanshuai@idys1 cut_dir] vim student_new.txt
1 ID Name gender Mark
2 1 Liming M 86
3 2 Sc M 90
4 3 Tg M 83
# 将空格替换为字符串
[dayuanshuai@idys1 cut_dir] sed -i "s/\ /\t/g" student_new.txt
# 再次查看文本,发现文本对齐了
[dayuanshuai@idys1 cut_dir] cat student_new.txt
ID Name gender Mark
1 Liming M 86
2 Sc M 90
3 Tg M 83
[dayuanshuai@idys1 cut_dir] sed '1d' student_new.txt | cut -f 2
Liming
Sc
Tg
:
作为分隔符[dayuanshuai@idys1 cut_dir] sed "1d" student_new.txt | awk 'BEGIN{IFS="\t"}{print $1":"$2}'
1:Liming
2:Sc
3:Tg
[dayuanshuai@idys1 cut_dir] head -2 student_new.txt | tail -1 | cut -c 3-4
Li
[dayuanshuai@idys1 cut_dir] grep -E ":\b[5-9][0-9][0-9]\b:" /etc/passwd | cut -d ":" -f 1
dayuanshuai
xiao
hadoop
test2
peiqi
cut
命令截取 df
命令的第一列和第三列# 首先查看内容
[dayuanshuai@idys1 cut_dir] df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 27G 3.3G 22G 14% /
tmpfs 931M 0 931M 0% /dev/shm
/dev/sda1 190M 36M 145M 20% /boot
/dev/sdb1 14M 139K 13M 2% /data
[dayuanshuai@idys1 cut_dir] df -h | sed -r "s/[[:space:]]+/ /g" | cut -d " " -f 1,3
Filesystem Used
/dev/sda3 3.3G
tmpfs 0
/dev/sda1 36M
/dev/sdb1 139K
awk
编程printf
格式化输出
使用形式
printf
输出类型输出格式 输出内容输出类型:
输出类型 | 含义 |
---|---|
%s |
输出字符串。n 是数字指代输出几个字符 |
%ni |
输出整数。n 是数字指代输出几个数字 |
%m.nf |
输出浮点数。m 和 n 是数字,指代输出的整数位数和小数位数。如%8.2f 代表共输出 8 位数,其中 2 位是小数,6 位是整数。 |
输出格式 | 含义 |
---|---|
\a |
输出警告声音 |
\b |
输出退格键,也就是 Backspace 键 |
\f |
清除屏幕 |
\n |
换行 |
\r |
回车,也就是 Enter 键 |
\t |
水平输出退格键,也就是 Tab 键 |
v |
垂直输出退格键,也就是 Tab 键 |
student_me.txt
# 可以看到文件没有对齐等
[dayuanshuai@idys1 cut_dir] vim student_me.txt
1 ID Name PHP Linux MySQL Average
2 1 idys 82 95 86 87.66
3 2 fool 74 96 87 85.66
4 3 itrh 99 83 93 91.66
# 将所有的空格替换为,制表符
[dayuanshuai@idys1 cut_dir] sed -ri 's/[[:space:]]+/\t/g' student_me.txt
# 再次查看文件,内容对齐
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
printf
输出文件内容[dayuanshuai@idys1 cut_dir] printf "%s" $(cat student_me.txt)
IDNamePHPLinuxMySQLAverage1idys82958687.662fool74968785.663itrh99839391.66[dayuanshuai@idys1 cut_dir] printf "%s" `cat student_me.txt`
IDNamePHPLinuxMySQLAverage1idys82958687.662fool74968785.663itrh99839391.66[dayuanshuai@idys1 cut_dir]
可以看到
printf
直接将文件内容全部输出,而没有进行换行,对齐等操作
%s
代表输出类型,\t
指代输出格式[dayuanshuai@idys1 cut_dir] printf "%s\t%s\t%s\t%s\t%s\t%s\n" $(cat student_me.txt)
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
m.n%
表示即可[dayuanshuai@idys1 cut_dir] printf "%s\t%s\t%s\t%s\t%s\t%s\n" `head -1 student_me.txt` ;printf "%3.1f\t%s\t%3.1f\t%3.1f\t%3.1f\t%3.1f\n" `sed '1d' student_me.txt`
ID Name PHP Linux MySQL Average
1.0 idys 82.0 95.0 86.0 87.7
2.0 fool 74.0 96.0 87.0 85.7
3.0 itrh 99.0 83.0 93.0 91.7
awk
基本使用
使用格式
awk
条件 1{动作 1} 条件 2{动作 2}… 文件名条件(pattern)
表达式 | 含义 |
---|---|
x > 10 |
判断变量 x 是否大于 10 |
x == y |
判断变量 x 是否等于变量 y |
A ~ B |
判断字符串 A 中是否包含能匹配 B 表达式的子字符串 |
A !~ B |
判断字符串 A 中是否不包含能匹配 B 表达式的子字符串 |
格式化输出的用法与演示
提取出df -h
显示的第1
列和第3
列,不显示第一行
# 先查看df -h的输出结果
[dayuanshuai@idys1 cut_dir] df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 27G 3.3G 22G 14% /
tmpfs 931M 0 931M 0% /dev/shm
/dev/sda1 190M 36M 145M 20% /boot
/dev/sdb1 14M 139K 13M 2% /data
# 不显示第一行查看第1列和第三列
[dayuanshuai@idys1 cut_dir] df -h | awk '{ if(NR>1) printf $1"\t"$3"\n"}'
/dev/sda3 3.3G
tmpfs 0
/dev/sda1 36M
/dev/sdb1 139K
# 换种方式写
[dayuanshuai@idys1 cut_dir] df -h | awk 'NR>1{printf $1"\t"$3"\n"}'
/dev/sda3 3.3G
tmpfs 0
/dev/sda1 36M
/dev/sdb1 139K
10%
的行# 首先查看磁盘使用量
[dayuanshuai@idys1 cut_dir] df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 27G 3.3G 22G 14% /
tmpfs 931M 0 931M 0% /dev/shm
/dev/sda1 190M 36M 145M 20% /boot
/dev/sdb1 14M 139K 13M 2% /data
# 显示出使用量大于 10%的磁盘
[dayuanshuai@idys1 cut_dir] df -h | sed -r "1,\$s/%//g" | awk 'NR>1{if($5>10)print $1"\t"$2"\t"$3"\t"$4"\t"$5"%""\t"$6}' | sed "1i`df -h | head -1`" | sed -r 's/[[:space:]]+/\t/g'
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 27G 3.3G 22G 14% /
/dev/sda1 190M 36M 145M 20% /boot
awk
条件条件的类型 | 条件 | 说明 |
---|---|---|
awk 保留字 |
BEGIN |
在 awk 程序一开始时,尚未读取任何数据之前执行。BEGIN 后的动作只在程序开始时执行一次 |
awk 保留字 |
END |
在awk 程序处理完所有数据,即将结束时执行。END 后的动作只在程序结束时执行一次 |
关系运算符 | > |
大于 |
关系运算符 | < |
小于 |
关系运算符 | >= |
大于等于 |
关系运算符 | <= |
小于等于 |
关系运算符 | == |
等于。用于判断两个值是否相等,如果是给变量赋值,请使用 = 号 |
关系运算符 | != |
不等于 |
关系运算符 | A~B |
判断字符串 A 中是否包含能匹配 B表达式的子字符串 |
关系运算符 | A!~B |
判断字符串 A 中是否不包含能匹配 B 表达式的子字符串 |
正则表达式 | /正则/ |
如果在// 中可以写入字符,也可以支持正则表达式 |
BEGIN
BEGIN
是 awk
的保留字,是一种特殊的条件类型。BEGIN
的执行时机是在 awk
程序一开始时, 尚未读取任何数据之前执行。一旦 BEGIN
后的动作执行一次,当 awk
开始从文件中读入数据,BEGIN
的条件就不再成立,所以 BEGIN
定义的动作只能被执行一次。演示
[dayuanshuai@idys1 cut_dir] df -h | awk 'BEGIN{print "============================"} END{print "============================"} {print $1"\t"$2$3$4$5}'
============================
Filesystem SizeUsedAvailUse%
/dev/sda3 27G3.3G22G14%
tmpfs 931M0931M0%
/dev/sda1 190M36M145M20%
/dev/sdb1 14M139K13M2%
============================
# 这里定义了两个动作
# 第一个动作使用 BEGIN 条件,所以会在读入文件数据前打印“====================”(只会执行一次)
#这里定义了两个动作
#第二个动作会打印文件1,2,3,4,5列字段
END
END
也是 awk
保留字,不过刚好和 BEGIN
相反。END
是在awk
程序处理完所有数据,即将结束时执行。END
后的动作只在程序结束时执行一次。例如:关系运算符
查看平均成绩大于87
的学生的姓名
# 首先查看文件内容
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
# 执行题目要求操作,打印出平均分大于 87的学生的姓名
[dayuanshuai@idys1 cut_dir] cat student_me.txt | awk 'NR>1{if($5>87) print $2}'
itrh
加入了条件之后,只有条件成立动作才会执行,如果条件不满足,则动作则不运行。通过这个实 验,大家可以发现,虽然
awk
是列提取命令,但是也要按行来读入的。这个命令的执行过程是这样的
如果有 BEGIN 条件,则先执行 BEGIN 定义的动作
如果没有 BEGIN
条件,则读入第一行,把第一行的数据依次赋予$0
、$1
、$2
等变量。其中$0
代表此行的整体数据,$1
代表第一字段,$2
代表第二字段
依据条件类型判断动作是否执行。如果条件符合,则执行动作,否则读入下一行数据。如果没有条件,则每行都执行动作
读入下一行数据,重复执行以上步骤
idys
的平均成绩[dayuanshuai@idys1 cut_dir] cat student_me.txt | awk 'NR>1{if($2 ~ /idys/) print $6}'
87.66
这里要注意在
awk
中,使用//
包含的字符串,awk
命令才会查找。也就是说字符串必须用//
包含,awk
命令才能正确识别
66
结尾的行[dayuanshuai@idys1 cut_dir] awk ' /66$/ {print}' student_me.txt
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
正则表达式
如果要想让 awk
识别字符串,必须使用//
包含,例如
提取出含有r
的行,而且行必须从第2
行到第4
行查找
[dayuanshuai@idys1 cut_dir] awk '/r/ {if(NR>1 && NR<=4) print}' student_me.txt
3 itrh 99 83 93 91.66
awk
判断IP
是否合法# 查看文件内容
[dayuanshuai@idys1 day5] tail -11 num_task_file.txt
123.45.12.123wq
q123.12.1.1c
1233.1234.1.12c
12.12.123.12
1.1.2.3
12.1.212.1.5
1.0.0.0
0.0.0.0
127.12.0.0
12.12.124.123.231.123
192.168.1.0
# 使用 -W re-interval 形式可以支持 {m,n}
# / / 内可以使用正则表达式
# if嵌套的形式为 if(判断式){if (判断式){执行动作}}
[dayuanshuai@idys1 day5] awk -W re-interval -F'.' '/^[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}$/ {if($1>0 && $1<255 && $2>=0 && $2<255 && $3>=0 && $3<255 && $4>=0 && $4<255) {if(!($2 == 0 && $3 == 0 && $4 == 0)) print $0}}' num_task_file.txt
12.12.123.12
127.12.0.0
192.168.1.0
# 另外一种形式
[dayuanshuai@idys1 day5] awk -W re-interval -F'.' '/^[[:digit:]].*[[:digit:]]$/ {if(NF == 4 && $1>0 && $1<255 && $2>=0 && $2<255 && $3>=0 && $3<255 && $4>=0 && $4<255) {if(!($2 == 0 && $3 == 0 && $4 == 0)) print $0}}' num_task_file.txt
12.12.123.12
127.12.0.0
192.168.1.0
awk
内置变量awk内置变量 | 作用 |
---|---|
$0 |
代表目前 awk 所读入的整行数据。我们已知 awk 是一行一行读入数据 的,$0 就代表当前读入行的整行数据。 |
$n |
代表目前读入行的第 n 个字段。 |
NF |
当前行拥有的字段(列)总数。 |
NR |
当前 awk 所处理的行,是总数据的第几行。 |
FS |
用户定义分隔符。awk 的默认分隔符是任何空格,如果想要使用其他分隔符(如: ),就需要 FS 变量定义。 |
ARGC |
命令行参数个数 |
ARGV |
命令行参数数组。 |
FNR |
当前文件中的当前记录数(对输入文件起始为 1 ) |
OFMT |
数值的输出格式(默认为%.6g ) |
OFS |
输出字段的分隔符(默认为空格) |
ORS |
输出记录分隔符(默认为换行符) |
RS |
输入记录分隔符(默认为换行符) |
awk
筛选出可以登录用户的用户名,UID
和匹配所在的行数[dayuanshuai@idys1 day5] awk 'BEGIN{FS=":"} /\/bin\/bash/{printf ("%-12s\t%s\t%s\n",$1,$3,NR)}' /etc/passwd
root 0 1
dayuanshuai 500 23
xiao 501 24
hadoop 502 25
sshd
这个伪用户的信息[dayuanshuai@idys1 day5] awk 'BEGIN{FS=":"} $1=="sshd" {print $1"\t"$3"\t行号为:"NR"\t字段数:"NF}' /etc/passwd
sshd 74 行号为:20 字段数:7
awk
流程控制
查看文件内容
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
PHP
科目成绩总分[dayuanshuai@idys1 cut_dir] awk '{grade+=$3}END{print "php sum grade="grade}' student_me.txt
php sum grade=255
PHP
科目平均分# NR 代表行数
[dayuanshuai@idys1 cut_dir] awk '{grade+=$3}END{print "php sum grade="grade/(NR-1)}' student_me.txt
php sum grade=85
awk
编程中,因为命令语句非常长,在输入格式时需要注意以下内容:
- 多个条件{动作}可以用空格分割,也可以用回车分割。
- 在一个动作中,如果需要执行多个命令,需要用
;
分割,或用回车分割。- 在
awk
中,变量的赋值与调用都不需要加入$
符- 条件中判断两个值是否相同,请使用
==
,以便和变量赋值进行区分。
[dayuanshuai@idys1 cut_dir] awk 'NR>=2 && NR<4 && $3>80{print $2"\tis a good man"}' student_me.txt
idys is a good man
awk
函数awk
编程也允许在编程时使用函数,形式如下function 函数名(参数列表){
函数体
}
# grade 为传入的参数,由于用户自己控制function 定义函数,之后调用函数
[dayuanshuai@idys1 cut_dir] awk 'function print_grade(grade){ if(NR>1 && $3>grade){print $2" is a good man"} }{ print_grade(80)}' student_me.txt
idys is a good man
itrh is a good man
awk
调用脚本
awk -f
脚本名即可导入脚本名
通过导入脚本名的方式,实现上述操作
[dayuanshuai@idys1 cut_dir] echo 'function print_grade(grade){ if(NR>1 && $3>grade){print $2" is a good man"} }{ print_grade(80)}' >input.awk; awk -f input.awk student_me.txt
idys is a good man
itrh is a good man
sed
命令sed
主要是用来将数据进行选取、替换、删除、新增的命令,我们看看命令的语sed
用法格式
sed
[选项] [动作] 文件名sed
选项选项 | 含义 |
---|---|
-n |
一般 sed 命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过 sed 命令处理的行输出到屏幕。 |
-e |
允许对输入数据应用多条 sed 命令编辑。 |
-f 脚本文件名 |
从 sed 脚本中读入 sed 操作。和 awk 命令的-f 非常类似 |
-r |
在 sed 中支持扩展正则表达式。 |
-i |
用 sed 的修改结果直接修改读取数据的文件,而不是由屏幕输出 |
sed
动作动作 | 含义 |
---|---|
动作: a \ |
追加,在当前行后添加一行或多行。添加多行时,除最后一行外, 每行末尾需要用\代表数据未完结 |
c \ |
行替换,用 c 后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用\ 代表数据未完结。 |
i \ |
插入,在当期行前插入一行或多行。插入多行时,除最后 一行外, 每行末尾需要用\ 代表数据未完结 |
d |
删除,删除指定的行 |
p |
打印,输出指定的行 |
s |
字串替换,用一个字符串替换另外一个字符串。格式为行范围 s/ 旧字串/新字串/g (和 vim 中的替换格式类似) |
g |
对数据中所有匹配到的内容进行替换,如果没有 g ,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A |
w file |
将缓冲区中的内容写到指定的 file 文件中 |
& |
用正则表达式匹配的内容进行替换 |
\n |
匹配第 n 个子串,该子串之前在 pattern 中用 \(\) 指定 |
对
sed
命令大家要注意,sed
所做的修改并不会直接改变文件的内容(如果是用管道符接收的命令的输出,这种情况连文件都没有),而是把修改结果只显示到屏幕上,除非使用“-i”选项才会直接修改文件
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
# 不加-n的话会将所有数据输出至屏幕
[dayuanshuai@idys1 cut_dir] sed '2p' student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
# 只显示第二行
[dayuanshuai@idys1 cut_dir] sed -n '2p' student_me.txt
1 idys 82 95 86 87.66
# 从第二行添加内容
[dayuanshuai@idys1 cut_dir] sed '2a whoami\
> how are you\
> and me?' student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
whoami
how are you
and me?
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
# 删除第二行
[dayuanshuai@idys1 cut_dir] sed '2d' student_me.txt
ID Name PHP Linux MySQL Average
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
[dayuanshuai@idys1 cut_dir] sed '4i whoami\
> how \
> are \
> you\
> ' student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
whoami
how
are
you
3 itrh 99 83 93 91.66
[dayuanshuai@idys1 cut_dir] sed -n '2i man\
> hello\
> ' student_me.txt
man
hello
82
替换为12
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
[dayuanshuai@idys1 cut_dir] sed '2s/82/12/' student_me.txt
ID Name PHP Linux MySQL Average
1 idys 12 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
h
替换为,|@|
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat service_test.txt
how how are are you
you are me are me how how are me
me is idiot idiot how are how
all work, no play, make jack fool
fstab
的文件grep
的参数说明
-R
在目录下递归查找-l
:只显示文件名,如果不使用-l
参数的话,那么就会既显示文件名,又显示文件名中对应匹配该字符串的行# 查找 /etc/ 目录下所有内容能与正则表达式匹配的文件,并且显示出该文件的文件名,及其与正则表达式匹配的行
[root@idys1 ~] grep -E '^root.*[[:digit:]]+.*[^:]$' -R /etc/
/etc/selinux/targeted/seusers:root:unconfined_u:s0-s0:c0.c1023
/etc/selinux/targeted/modules/active/seusers.final:root:unconfined_u:s0-s0:c0.c1023
/etc/passwd:root:x:0:0:root:/root:/bin/bash
/etc/services:rootd 1094/tcp # ROOTD
/etc/services:rootd 1094/udp # ROOTD
/etc/passwd-:root:x:0:0:root:/root:/bin/bash
# 加了 -l 参数后,只显示文件名
[root@idys1 ~] grep -E '^root.*[[:digit:]]+.*[^:]$' -Rl /etc/
/etc/selinux/targeted/seusers
/etc/selinux/targeted/modules/active/seusers.final
/etc/passwd
/etc/services
/etc/passwd-
/home
目录下,查找后缀名为.txt
的文件里面内容中与正则表达式匹配的文件。找出来之后显示文件名。行号。及其匹配的行.# grep -n 显示行号 -E 支持扩展正则 -R 文件夹下递归查找
[root@idys1 ~] grep -RnE --include="*.txt" '^[[:digit:]]+[[:space:]]+idys' /home
/home/dayuanshuai/day5/cut_dir/student_me.txt:2:1 idys 82 95 86 87.66
sed
对文件进行修改,同时为该文件做一个备份# 首先 查看文件内容
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
# 查看该目录下有哪些文件
[dayuanshuai@idys1 cut_dir] ls
input.awk service_test.txt student_me.txt student_me.txt.bak student.txt
# 修改student_me.txt文件,在文件第二行 添加 whoami
[dayuanshuai@idys1 cut_dir] sed -i.bak '2a whoami' student_me.txt
# 查看目录下的文件,发现多出一个 student_me.txt.bak 文件
[dayuanshuai@idys1 cut_dir] ls
87 input.awk service_test.txt student_me.txt student_me.txt.bak student.txt
# 查看student_me.txt.bak和student_me.txt文件
[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
whoami
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
[dayuanshuai@idys1 cut_dir] cat student_me.txt.bak
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
sed
,查找idys
,在其后面添加换行符[dayuanshuai@idys1 cut_dir] sed 's/idys/&\n/g' student_me.txt
ID Name PHP Linux MySQL Average
1 idys
82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
idys
字符串,在其前面添加换行[dayuanshuai@idys1 cut_dir] sed 's/idys/\n&/g' student_me.txt
ID Name PHP Linux MySQL Average
1
idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
idys
这一行,然后将idys
这一行的内容写入到新文件当中# 匹配含有idys字符串的哪一行,然后将其写入到 A.txt 文件中
# w 后接文件名 表示将匹配到的内容 写入到新文件中
[dayuanshuai@idys1 cut_dir] sed -n '/idys/w A.txt' student_me.txt
[dayuanshuai@idys1 cut_dir] cat A.txt
1 idys 82 95 86 87.66
# & 代表前面匹配到的内容
[dayuanshuai@idys1 cut_dir] sed '2,3s/.*/&\n&/g' student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
id
和姓名[dayuanshuai@idys1 cut_dir] cat student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
# 使用 -e 可以使用多条命令匹配, \(\)用于匹配整个\(\)里面的内容,\1引用前面\(\)里面的内容
[dayuanshuai@idys1 cut_dir] sed -e 's/\([[:digit:]]\)[[:space:]]\+\([[:alpha:]]\+\).*/\1\t\2/g' -e '1d' student_me.txt
1 idys
2 fool
3 itrh
# 开启扩展正则表达式
[dayuanshuai@idys1 cut_dir] sed -r -e 's/([[:digit:]])[[:space:]]+([[:alpha:]]+).*/\1\t\2/g' -e '1d' student_me.txt
1 idys
2 fool
3 itrh
sed
把某个单词替换为另外一个字符串# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat sed_test.txt
my A A a ha hahaha who who
w who who w who my
my m m f for for in i in
# 想将 单独的 a 替换为 lol, 如果使用以下命令, 则会将所有的a替换为lol
[dayuanshuai@idys1 cut_dir] sed 's/a/lol/g' sed_test.txt
my A A lol hlol hlolhlolhlol who who
w who who w who my
my m m f for for in i in
# 以下才是正确的将 单独的A单词替换为 lol
[dayuanshuai@idys1 cut_dir] sed 's/\/lol/g' sed_test.txt
my A A lol ha hahaha who who
w who who w who my
my m m f for for in i in
# 把单独的a单词替换为lol,同时不区分大小写
[dayuanshuai@idys1 cut_dir] sed 's/\/lol/ig' sed_test.txt # 这种形式 's///i'即使不区分大小写,替换
my lol lol lol ha hahaha who who
w who who w who my
my m m f for for in i in
# 不区分who的大小写,将其全局替换为 Love
[dayuanshuai@idys1 cut_dir] sed 's/who/Love/ig' sed_test.txt
my A A a ha hahaha Love Love
w Love Love w Love my
my m m f fOr For FOR in i in
w
替换为me
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat sed_test.txt
my A A a ha hahaha who who
w who Who w wHo my
my m m f fOr For FOR in i in
# 将每行中的第2个w替换为 me
[dayuanshuai@idys1 cut_dir] sed 's/w/me/i2' sed_test.txt
my A A a ha hahaha who meho
w meho Who w wHo my
my m m f fOr For FOR in i in
2
个w
开始替换为L
# 's///2g'代表从第2个开始进行替换
[dayuanshuai@idys1 cut_dir] sed 's/w/L/i2g' sed_test.txt
my A A a ha hahaha who Lho
w Lho Lho L LHo my
my m m f fOr For FOR in i in
a
替换为Q
# 0,/要替换的内容/s/要替换的内容/替换后的内容/
# 替换第一行第一个a
[dayuanshuai@idys1 cut_dir] sed '0,/a/s/a/Q/i' sed_test.txt
my Q A a ha hahaha who who
w who Who w wHo my
my m m f fOr For FOR in i in
a
[dayuanshuai@idys1 cut_dir] sed '0,/a/s/a/Q/ig' sed_test.txt
my Q Q Q hQ hQhQhQ who who
w who Who w wHo my
my m m f fOr For FOR in i in
# 替换第一行的所有a
[dayuanshuai@idys1 cut_dir] sed '1s/a/Q/g' sed_test.txt
my A A Q hQ hQhQhQ who who
w who Who w wHo my
my m m f fOr For FOR in i in
o
替换为Q
# 1, 代表前两行
[dayuanshuai@idys1 cut_dir] sed '1,/o/s/o/Q/g' sed_test.txt
my A A a ha hahaha whQ whQ
w whQ WhQ w wHQ my
my m m f fOr For FOR in i in
o
替换为Q
[dayuanshuai@idys1 cut_dir] sed '1,/o/s/o/Q/' sed_test.txt
my A A a ha hahaha whQ who
w whQ Who w wHo my
my m m f fOr For FOR in i in
/
在sed
命令中作为定界符使用,其实任意字符都可以当作定界符# 第二行第二个 w 替换为 kk
[dayuanshuai@idys1 cut_dir] sed '2s|w|kk|2' sed_test.txt
my A A a ha hahaha who who
w kkho Who w wHo my
my m m f fOr For FOR in i in
who
的行删除[dayuanshuai@idys1 cut_dir] sed '/\/d' sed_test.txt
my m m f fOr For FOR in i in
[]
[dayuanshuai@idys1 cut_dir] sed -r '1s/\w+/[&]/g' sed_test.txt
[my] [A] [A] [a] [ha] [hahaha] [who] [who]
w who Who w wHo my
my m m f fOr For FOR in i in
Sed
命令还可以组合多个表达式# 首先全局替换然后,删除,最后插入
[dayuanshuai@idys1 cut_dir] sed -r 's/who/idys/g;2d; 1a sdasdsadasd' sed_test.txt
my A A a ha hahaha idys idys
sdasdsadasd
my m m f fOr For FOR in i in
# 这个似乎没有起作用
[dayuanshuai@idys1 cut_dir] sed -r 's/who/idys/g;2d; 2a sdasdsadasd' sed_test.txt
my A A a ha hahaha idys idys
my m m f fOr For FOR in i in
# 写在第3行后面添加就有效了
[dayuanshuai@idys1 cut_dir] sed -r 's/who/idys/g;2d; 3a sdasdsadasd\n' sed_test.txt
my A A a ha hahaha idys idys
my m m f fOr For FOR in i in
sdasdsadasd
# 最后一行,后面添加 sdasdsadasd
[dayuanshuai@idys1 cut_dir] sed -r 's/who/idys/g;2d; $a sdasdsadasd\n' sed_test.txt
my A A a ha hahaha idys idys
my m m f fOr For FOR in i in
sdasdsadasd
sed
实现值得提取# 文本内容如下。现在我们要将 所有的 value 提取出来
[dayuanshuai@idys1 cut_dir] cat my_task1.txt
type1=value1 type2=value2 type3=value3
type1=value1 type2=value2 type3=value3
# 这样即可
[dayuanshuai@idys1 cut_dir] sed -r 's/[^[:space:]]+=//g' my_task1.txt
value1 value2 value3
value1 value2 value3
/bin/bash
修改为/bin/sh
,同时打印输出,修改的行[dayuanshuai@idys1 cut_dir] sed -n 's|/bin/bash|/bin/sh|gp' /etc/passwd
root:x:0:0:root:/root:/bin/sh
dayuanshuai:x:500:500::/home/dayuanshuai:/bin/sh
xiao:x:501:501::/home/xiao:/bin/sh
hadoop:x:502:502::/home/hadoop:/bin/sh
name
[dayuanshuai@idys1 cut_dir] sed -r '2,4s/[[:alpha:]]+//g' student_me.txt
ID Name PHP Linux MySQL Average
1 82 95 86 87.66
2 74 96 87 85.66
3 99 83 93 91.66
idys
前后各一行,中的人名[dayuanshuai@idys1 cut_dir] sed -re '2s/[[:alpha:]]+//g;4s/[[:alpha:]]+//g' student_me.txt
ID Name PHP Linux MySQL Average
1 82 95 86 87.66
2 fool 74 96 87 85.66
3 99 83 93 91.66
# $ 代表最后一行, & 指代前面匹配的内容
[dayuanshuai@idys1 cut_dir] sed -r "2,\$s/.*/&\n&/g" student_me.txt
ID Name PHP Linux MySQL Average
1 idys 82 95 86 87.66
1 idys 82 95 86 87.66
2 fool 74 96 87 85.66
2 fool 74 96 87 85.66
3 itrh 99 83 93 91.66
3 itrh 99 83 93 91.66
# 在 echo "2" 后面添加 echo "3"
[dayuanshuai@idys1 cut_dir] sed '/echo "2"/a \echo "3";' echo_test_txt
echo "1";
echo "2";
echo "3";
echo "4";
echo "5";
# 在第二行后面添加 echo "3"
[dayuanshuai@idys1 cut_dir] sed '2a echo "3";' echo_test_txt
echo "1";
echo "2";
echo "3";
echo "4";
echo "5";
[dayuanshuai@idys1 cut_dir] sed '/[^[:space:]]/a \ ' echo_test_txt
echo "1";
echo "2";
echo "4";
echo "5";
# G 代表将 将hold space中的内容拷贝到pattern space中
[dayuanshuai@idys1 cut_dir] sed 'G' echo_test_txt
echo "1";
echo "2";
echo "4";
echo "5";
sed
保留空间与模式空间的操作命令命令 | 含义 |
---|---|
g :[address[,address]]g |
将hold space 中的内容拷贝到pattern space 中,原来pattern space 里的内容清除 |
G :[address[,address]]G |
将hold space 中的内容append 到pattern space\n 后。 |
h :[address[,address]]h |
将pattern space 中的内容拷贝到hold space 中,原来的hold space 里的内容被清除。 |
H :[address[,address]]H |
将pattern space 中的内容append 到hold space\n 后。 |
d :[address[,address]]d |
删除pattern 中的所有行,并读入下一新行到pattern 中。 |
D :[address[,address]]D |
删除multiline pattern 中的第一行,不读入下一行。 |
x |
交换保持空间和模式空间的内容。 |
p |
打印当前模式空间内容,追加到默认输出之后 |
P |
打印当前模式空间开端至\n 的内容,并追加到默认输出之前 |
n |
命令简单来说就是提前读取下一行,覆盖模型空间前一行(并没有删除,因此依然打印至标准输出),如果命令未执行成功(并非跳过:前面条件不匹配),则放弃执行之后的任何命令,并对新读取的内容,重头执行sed |
N |
命令简单来说就是追加下一行到模式空间,同时将两行看做一行,但是两行之间依然含有\n 换行符,如果命令未执行成功(并非跳过:前面条件不匹配),则放弃之后任何命令,并对新读取的内容,重头执行sed |
1!G |
第一行不执行G命令,从第二行开始执行 |
$!d |
最后一行不删除 |
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat echo_test_txt
echo "1";
echo "2";
echo "3";
echo "4";
echo "5";
# 打印输出奇数数行
[dayuanshuai@idys1 cut_dir] sed -n '$!N;P' echo_test_txt
echo "1";
echo "3";
echo "5";
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat echo_T2.txt
echo "1";
echo "2";
echo "3";
echo "4";
# 打印输出奇数行
[dayuanshuai@idys1 cut_dir] sed -n '$!N;P' echo_T2.txt
echo "1";
echo "3";
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat echo_test_txt
echo "1";
echo "2";
echo "3";
echo "4";
echo "5";
# 打印输出偶数行
[dayuanshuai@idys1 cut_dir] sed -n 'n;p' echo_test_txt
echo "2";
echo "4";
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat echo_T2.txt
echo "1";
echo "2";
echo "3";
echo "4";
# 打印输出所有的偶数行
[dayuanshuai@idys1 cut_dir] sed -n 'n;p' echo_T2.txt
echo "2";
echo "4";
# 查看文件内容
[dayuanshuai@idys1 cut_dir] cat echo_test_txt
echo "1";
echo "2";
echo "3";
echo "4";
echo "5";
# 倒序输出所有奇数行, 1!G 第一行不执行 G,
# G 将 hold space 里面的内容复制追加到 pattern space 里面
# N 直接读取两行,行中用\n 隔开,
# s/// 替换
# h 将 patter space 里面的内容 复制覆盖到 hold space里面
# !$d 最后一行不执行 删除
[dayuanshuai@idys1 cut_dir] sed -r '1!G;N;s/(.*)\n(.*)/\1/;h;$!d' echo_test_txt
echo "5";
echo "3";
echo "1";
[dayuanshuai@idys1 cut_dir] cat echo_T2.txt
echo "1";
echo "2";
echo "3";
echo "4";
# 倒序输出所有的奇数行
[dayuanshuai@idys1 cut_dir] sed -r '1!G;N;s/(.*)\n(.*)/\1/g;h;$!d' echo_T2.txt
echo "3";
echo "1";
# 先输出所有偶数行,然后倒序
[dayuanshuai@idys1 cut_dir] sed -n 'n;p' echo_T2.txt | sed '1!G;h;$!d'
echo "4";
echo "2";
# 原字符串内容
[dayuanshuai@idys1 cut_dir] cat echo_test_txt
echo "1";
echo "2";
echo "3";
echo "4";
echo "5";
# rev 代表逆序输出字符串
[dayuanshuai@idys1 cut_dir] sed -r '1!G;N;s/(.*)\n(.*)/\1/g;h;$!d' echo_test_txt | rev
;"5" ohce
;"3" ohce
;"1" ohce
# 倒序输出字符串
[dayuanshuai@idys1 ~] str=hello;len=${#str};for((i=$len-1;i>=0;i--));do echo -e "${str:$i:1}\c";done;echo -e "\n"
olleh
# 数组的形式倒序输出
[dayuanshuai@idys1 cut_dir] str=`echo "hello" | sed 's/./& /g'`;array=($str);len=${#array[@]};for((i=$len-1;i>=0;i--));do echo -e "${array[$i]}\c";done;echo -e "\n"
olleh
# 发现倒序输出对有空格的无效,倒序后没有打印空格
[dayuanshuai@idys1 cut_dir] str=`echo "hello world" | sed 's/./& /g'`;array=($str);len=${#array[@]};for((i=$len-1;i>=0;i--));do echo -e "${array[$i]}\c";done;echo -e "\n"
dlrowolleh
sed
流程控制
b
:无条件跳转t
,T
:有条件跳转如果一行中,含有AA
,那么就在AA
后面末尾添加,YES
,反之添加NO
# 咦,我们发现 匹配到AA 的行,会在价位加 YES,没错。但是没有匹配到 AA的行却在结尾加上了
# NO 和 YES,这是为什么呢。这是因为,如果匹配到了AA那么直接跳转到 LABEL,如果没有匹配到AA的话,则会先执行 s/$/ NO/g 语句,然后 执行 s/$/ YES/g。这就是 NO和 YES都出现的原因
[dayuanshuai@idys1 sed_test] sed '/AA/b LABEL; s/$/ NO/g;:LABEL;s/$/ YES/g' sed_b.txt
AA YES
BC NO YES
AA YES
CB NO YES
CC NO YES
AA YES
# 解决办法,在NO后面的语句里面,再加上一个 b 语句,则不会继续执行LABEL 后面的语句
[dayuanshuai@idys1 sed_test] sed '/AA/b LABEL; s/$/ NO/g;b;:LABEL;s/$/ YES/g' sed_b.txt
AA YES
BC NO
AA YES
CB NO
CC NO
AA YES
sed
命令的b
语句详解# 如果匹配到了 /AA/ 那么跳转到 top 执行 s/$/who/g,如果没有匹配到 /AA/ 那么先执行s/$/NO/g
# 再执行s/$/am/g 最后执行 s/$/who/g
[dayuanshuai@idys1 sed_test] sed '/AA/b top;s/$/NO/g;s/$/am/g;:top;s/$/who/g' sed_b.txt
AAwho
BCNOamwho
AAwho
CBNOamwho
CCNOamwho
AAwho
# 因为 b 后面没有写 跳转标签。 那么当匹配到 /AA/ 时,直接跳转到行尾,什么也不执行。如果没有匹配到AA,那么则 一直往后执行语句 ( 先执行 s/$/NO/g 然后执行 s/$/am/g 最后执行 s/$/who/g )
[dayuanshuai@idys1 sed_test] sed '/AA/b;s/$/NO/g;:top;s/$/am/g;s/$/who/g' sed_b.txt
AA
BCNOamwho
AA
CBNOamwho
CCNOamwho
AA
t
命令# 倘若 前面 命令正确执行,那么t 直接跳转到行尾。什么都不执行。
# 倘若 前面的 命令没有执行成功。那么则 往下执行 s/$/ NO/g
[dayuanshuai@idys1 sed_test] sed '/^AA/s/$/ YES/g; t; s/$/ NO/g' sed_b.txt
AA YES
BC NO
AA YES
CB NO
CC NO
AA YES
# 查看命令的执行情况
[dayuanshuai@idys1 sed_test] sed '$a ww' sed_b.txt
AA
BC
AA
CB
CC
AA
ww
# 在 sed 命令后面添加 新的一行。 为 ww
[dayuanshuai@idys1 sed_test] sed -i '$a ww' sed_b.txt
# 一次读取 两行, 然后打印第一行。 t 用于判断。 前面是否正确执行。 执行成功 跳转到 LABEL, 不成功则往后执行
[dayuanshuai@idys1 sed_test] sed -n ':LABEL; $!N;P;t LABEL' sed_b.txt
AA
AA
CC
ww
sed
命令的y
s
替换的是整体,y
替换的是每一字母对应的单个字母y
和s
的区别演示# 首先查看文件内容
[dayuanshuai@idys1 sed_test] cat sed_y_s_test.txt
ABC AB A C
ABCDE ABC A BC
CBA BA CA
# 将单个字母A替换为w 将单个字母B替换为h 将单个字母C替换为o
[dayuanshuai@idys1 sed_test] sed 'y/ABC/who/' sed_y_s_test.txt
who wh w o
whoDE who w ho
ohw hw ow
# 将ABC作为一个整体替换为 who
[dayuanshuai@idys1 sed_test] sed 's/ABC/who/g' sed_y_s_test.txt
who AB A C
whoDE who A BC
CBA BA CA
使用格式
sort
[选项] 文件名选项及其含义
选项 | 含义 |
---|---|
-f |
忽略大小写 |
-b |
忽略每行前面的空白部分 |
-n |
以数值型进行排序,默认使用字符串型排序 |
-r |
反向排序 |
-u |
删除重复行。就是 uniq 命令 |
-t |
指定分隔符,默认是分隔符是制表符 |
-kn[,m] |
按照指定的字段范围排序。从第 n 字段开始,m 字段结束(默认到行尾) |
sort
命令默认是用每行开头第一个字符来进行排序的
将/etc/passwd
文件里面按照UID
来排序,排出来的结果只显示name
和UID
# 首先查看文件内容
[dayuanshuai@idys1 sed_test] cat /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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
***************************************
**********************
# 用 sort 排序。然后用 awk输出
[dayuanshuai@idys1 sed_test] sort -t":" -k 3 -n /etc/passwd | awk -F":" '{printf ("%-15s%-5i\n",$1,$3)}'
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 11
games 12
gopher 13
ftp 14
ntp 38
vcsa 69
sshd 74
dbus 81
postfix 89
nobody 99
dhcpd 177
saslauth 499
dayuanshuai 500
xiao 501
hadoop 502
test2 503
peiqi 504
# 利用 cat 提取出 内容
[dayuanshuai@idys1 sed_test] sort -t":" -k 3 -n /etc/passwd | cut -d":" -f1,3
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
uucp:10
operator:11
games:12
gopher:13
ftp:14
ntp:38
vcsa:69
sshd:74
dbus:81
postfix:89
nobody:99
dhcpd:177
saslauth:499
dayuanshuai:500
xiao:501
hadoop:502
test2:503
peiqi:504
/etc/passwd
按照UID
数字大小排序,排序后显示用户名和UID
,然后显示最后10
行和前9
行[dayuanshuai@idys1 sed_test] sort -t":" -k 3 -rn /etc/passwd | cut -d":" -f1,3 | awk '{line[NR]=$0} END{for(i=1;i<=NR;i++){if(i==10){i=NR-9}print line[i]} }'
peiqi:504
test2:503
hadoop:502
xiao:501
dayuanshuai:500
saslauth:499
dhcpd:177
nobody:99
postfix:89
uucp:10
mail:8
halt:7
shutdown:6
sync:5
lp:4
adm:3
daemon:2
bin:1
root:0
uniq
命令是用来取消重复行的命令,其实和sort -u
选项是一样的。命令格式如下uniq
[选项] 文件名uniq -i
忽略大小写uniq -c
:显示重复的次数uniq -d
:只显示重复的行uniq -u
:只显示出现一次的行-f n
或--skip-fields=n
忽略前N
个字段。字段由空白字符(空格符、Tab)分隔-s
<字符位置>或--skip-chars=
<字符位置> 忽略比较指定的字符。-s n:忽略前n个字符,从n+1个字符开始比较-w
<字符位置>或--check-chars=
<字符位置> 指定要比较的字符。-w n:只比较前n个字符,对每行第n个字符以后的内容不作对照[dayuanshuai@idys1 sed_test] seq 10 | sed -r 's/.*/&\n&/g' | sed -r '10,$s/.*/&\n&wqe/g'
1
1
2
2
3
3
4
4
5
5
5wqe
6
6wqe
6
6wqe
7
7wqe
7
7wqe
8
8wqe
8
8wqe
9
9wqe
9
9wqe
10
10wqe
10
10wqe
# 上面的内容有很多重复的,而且有些重复得内容不是连续的。现在我们想要将 重复不连续的行也删除
# 将这些内容先排序,后删除重复。就可以解决重复不连续的问题
[dayuanshuai@idys1 sed_test] seq 10 | sed -r 's/.*/&\n&/g' | sed -r '10,$s/.*/&\n&wqe/g' | sort -n | uniq
1
2
3
4
5
5wqe
6
6wqe
7
7wqe
8
8wqe
9
9wqe
10
10wqe
[dayuanshuai@idys1 sed_test] cat uniq_d.txt
AA
AA
AA
BB
# -d 只显示重复的行
[dayuanshuai@idys1 sed_test] uniq -dc uniq_d.txt
3 AA
# 只显示重复一次的行
[dayuanshuai@idys1 sed_test] uniq -uc uniq_d.txt
1 BB
wc
wc
[选项] 文件名选项 | 含义 |
---|---|
-l |
只统计行数 |
-w |
只统计单词数 |
-m |
只统计字符数 |
# sed -ri 's/.*/&\n&/g' sed_y_s_test.txt 将每一行重复一遍
# num=`wc -l sed_y_s_test.txt | cut -d" " -f1` 得出总行数
# sed -i '5,'"$(($num-1))"'y/B/b/' sed_y_s_test.txt 将变量num引入sed 中,从第五行到最后一行的前一行都把大写字母 B 变为小写字母b
# 这样下来该文本含有重复的行,而且含有重复不连续的行,而且也含有字母大小不一致,但是内容相等的行
[dayuanshuai@idys1 sed_test] sed -ri 's/.*/&\n&/g' sed_y_s_test.txt;num=`wc -l sed_y_s_test.txt | cut -d" " -f1`;sed -i '5,'"$(($num-1))"'y/B/b/' sed_y_s_test.txt
[dayuanshuai@idys1 sed_test] cat sed_y_s_test.txt
ABC AB A C
ABC AB A C
ABCDE ABC A BC
ABCDE ABC A BC
CbA bA CA
CbA bA CA
CbA bA CA
CbA bA CA
AbCDE AbC A bC
AbCDE AbC A bC
CbA bA CA
CbA bA CA
AbCDE AbC A bC
AbCDE AbC A bC
CbA bA CA
CBA BA CA
# 统计重复的行,而且显示重复的次数,忽略大小写
[dayuanshuai@idys1 sed_test] sort -f sed_y_s_test.txt | uniq -ic
2 ABC AB A C
6 AbCDE AbC A bC
8 CbA bA CA
测试选项 | 作用 |
---|---|
-b 文件 |
判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) |
-c 文件 |
判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真) |
-d 文件 |
判断该文件是否存在,并且是否为目录文件(是目录为真) |
-e 文件 |
判断该文件是否存在(存在为真) |
-f 文件 |
判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 |
判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真) |
-p 文件 |
判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-s 文件 |
判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 |
判断该文件是否存在,并且是否为套接字文件(是套接字文件为真) |
if
,elif
,else
语句写为一行# 判断 /root/fstab 文件是否存在,然后判断 /etc/fatab 文件是否存在
[dayuanshuai@idys1 sed_test] if [ -e /root/fastab ]; then echo "/root/fatab yes";elif [ -e /etc/fstab ];then echo "/etc/fstab yes";else echo "NO"; fi;
/etc/fstab yes
test
命令测试,以下测试目录# 测试目录是否存在
[dayuanshuai@idys1 sed_test] test -d /root;echo $?
0
if
的分支语句[dayuanshuai@idys1 sed_test] [ -e /etc/fatab ] && echo "yes" || echo "NO"
NO
测试选项 | 作用 |
---|---|
-r 文件 |
判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真) |
-w 文件 |
判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真) |
-x 文件 |
判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真) |
-u 文件 |
判断该文件是否存在,并且是否该文件拥有 SUID 权限(有 SUID 权限为真) |
-g 文件 |
判断该文件是否存在,并且是否该文件拥有SGID 权限(有 SGID 权限为真) |
-k 文件 |
判断该文件是否存在,并且是否该文件拥有 SBit 权限(有 SBit 权限为真) |
[dayuanshuai@idys1 sed_test] ls -l
总用量 12
-rw-rw-r-- 1 dayuanshuai dayuanshuai 21 8月 13 18:04 sed_b.txt
-rw-rw-r-- 1 dayuanshuai dayuanshuai 200 8月 14 00:22 sed_y_s_test.txt
-rw-rw-r-- 1 dayuanshuai dayuanshuai 12 8月 14 00:36 uniq_d.txt
[dayuanshuai@idys1 sed_test] [ -w sed_b.txt ] && echo "yes" || echo "No"
yes
测试选项 | 作用 |
---|---|
文件 1 -nt 文件 2 |
判断文件1 的修改时间是否比文件2 的新(如果新则为真) |
文件 1 -ot 文件 2 |
判断文件1 的修改时间是否比文件2 的旧(如果旧则为真) |
文件 1 -ef 文件 2 |
判断文件1 是否和文件2 的 Inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
# 首先创建一个文件
[dayuanshuai@idys1 sed_test] ln sed_y_s_test.txt sed_y_s_test.txt.hard_ln
# 判断是否为硬链接
[dayuanshuai@idys1 sed_test] [ sed_y_s_test.txt -ef sed_y_s_test.txt ] && echo "YES" || echo "NO"
YES
测试选项 | 作用 |
---|---|
整数 1 -eq 整数 2 |
判断整数 1 是否和整数 2 相等(相等为真) |
整数 1 -ne 整数 2 |
判断整数 1 是否和整数 2 不相等(不相等位置) |
整数 1 -gt 整数 2 |
判断整数 1 是否大于整数 2(大于为真) |
整数 1 -lt 整数 2 |
判断整数 1 是否小于整数 2(小于位置) |
整数 1 -ge 整数 2 |
判断整数 1 是否大于等于整数 2(大于等于为真) |
整数 1 -le 整数 2 |
判断整数 1 是否小于等于整数 2(小于等于为真) |
[dayuanshuai@idys1 sed_test] [ 103 -ge 103 ] && echo "YES" || echo "NO"
YES
测试选项 | 作用 |
---|---|
-z 字符串 |
判断字符串是否为空(为空返回真) |
-n 字符串 |
判断字符串是否为非空(非空返回真) |
字串 1 ==字串 2 |
判断字符串 1 是否和字符串 2 相等(相等返回真) |
字串 1 != 字串 2 |
判断字符串 1 是否和字符串 2 不相等(不相等返回真) |
# 定义 数组 array[0]为 12 array[1] 为23
[dayuanshuai@idys1 sed_test] array[0]=12
[dayuanshuai@idys1 sed_test] array[1]=23
# 遍历数组
[dayuanshuai@idys1 sed_test] for((i=0;i<=1;i++));do echo ${array[$i]};done
12
23
# 打印数组的所有元素
[dayuanshuai@idys1 sed_test] echo ${array[*]}
12 23
[dayuanshuai@idys1 sed_test] echo ${array[@]}
12 23
# 定义数组
[dayuanshuai@idys1 sed_test] array=(12 34 56 12 15 16 89 97)
# 遍历数组
[dayuanshuai@idys1 sed_test] for i in ${array[@]};do echo $i;done
12
34
56
12
15
16
89
97
# 获得数组长度
[dayuanshuai@idys1 sed_test] len=${#array[@]}
[dayuanshuai@idys1 sed_test] echo $len
8
# 获得数组的某个下标的值
[dayuanshuai@idys1 sed_test] echo ${array[2]}
56
# 定义数组
[dayuanshuai@idys1 sed_test] my_day=([1]=ha [2]=wu [3]=he [4]=id)
# 遍历数组
[dayuanshuai@idys1 sed_test] len=${#my_day[@]};for((i=1;i<$len;i++));do echo ${my_day[$i]};done
ha
wu
he
# 打印数组元素
[dayuanshuai@idys1 sed_test] echo ${my_day[@]}
ha wu he id
# 可以看到以 for in 的方式获得数组元素时, 不加双引号。 * 与 @ 得到的结果一样
# 加了双引号 会把 ${my_day[*]}看作一个整体,直接输出, 而${my_day[@]}仍然遍历数组元素
[dayuanshuai@idys1 sed_test] for i in ${my_day[*]};do echo $i;done
ha
wu
he
id
[dayuanshuai@idys1 sed_test] for i in ${my_day[@]};do echo $i;done
ha
wu
he
id
[dayuanshuai@idys1 sed_test] for i in "${my_day[@]}";do echo $i;done
ha
wu
he
id
[dayuanshuai@idys1 sed_test] for i in "${my_day[*]}";do echo $i;done
ha wu he id
# 销毁前面一个数组,然后重新定义数组
[dayuanshuai@idys1 sed_test] unset my_day
[dayuanshuai@idys1 sed_test] echo ${my_day[@]}
[dayuanshuai@idys1 sed_test] my_day=([0]="hello world" [1]="mysql" [2]="hei you")
# 可以看到加了 双引号 与没加双引号输出的区别, for in 时候,如果没有加双引号会以空格为分割
[dayuanshuai@idys1 sed_test] for i in ${my_day[@]};do echo $i;done
hello
world
mysql
hei
you
[dayuanshuai@idys1 sed_test] for i in "${my_day[@]}";do echo $i;done
hello world
mysql
hei you
# 打印数组所有下标元素
[dayuanshuai@idys1 sed_test] echo ${!my_day[@]}
0 1 2
# 给数组 添加元素
[dayuanshuai@idys1 sed_test] my_day+=("spanning tree")
# 打印所有下标元素
[dayuanshuai@idys1 sed_test] echo ${!my_day[@]}
0 1 2 3
# 取消数组下标元素。然后打印数组所有下标
[dayuanshuai@idys1 sed_test] unset my_day[0]
[dayuanshuai@idys1 sed_test] echo ${!my_day[@]}
1 2 3
# 判断 test_str 变量
[dayuanshuai@idys1 sed_test] [ -z "$test_str" ] && echo "yes" || echo "no"
no
[dayuanshuai@idys1 sed_test] [ -z $test_str ] && echo "yes" || echo "no"
no
# 这个就不是判断变量了
[dayuanshuai@idys1 sed_test] [ -z test_str ] && echo "yes" || echo "no"
no
[dayuanshuai@idys1 sed_test] [ -z who ] && echo "yes" || echo "no"
no
# 这是是判断 变量是否为空
[dayuanshuai@idys1 sed_test] [ -z $who ] && echo "yes" || echo "no"
yes
[dayuanshuai@idys1 sed_test] [ -z "$who" ] && echo "yes" || echo "no"
yes
# 判断两个元素是否相等。如果相等,那么则 打印 yes; 如果不等 则 打印 no
[dayuanshuai@idys1 sed_test] aa=11
[dayuanshuai@idys1 sed_test] bb=11
[dayuanshuai@idys1 sed_test] [ $aa == $bb ] && echo "yes" || echo "no"
yes
[dayuanshuai@idys1 sed_test] [ $aa == "11" ] && echo "yes" || echo "no"
yes
[dayuanshuai@idys1 sed_test] [ $aa == "1" ] && echo "yes" || echo "no"
no
测试选项 | 含义 |
---|---|
判断 1 -a 判断 2 |
逻辑与,判断 1 和判断 2 都成立,最终的结果才为真 |
判断 1 -o 判断 2 |
逻辑或,判断 1 和判断 2 有一个成立,最终的结果就为真 |
!判断 |
逻辑非,使原始的判断式取反 |
# num1 的值为 22
[dayuanshuai@idys1 day6] num1=22
[dayuanshuai@idys1 day6] [ -n "$num1" -a "$num1" -gt 34 ] && echo yes || echo no
no
[dayuanshuai@idys1 day6] [ -n $num1 -a $num1 -gt 34 ] && echo yes || echo no
no
# 判断 num1 的值是否不会空, 且是否大于1
[dayuanshuai@idys1 day6] [ -n $num1 -a $num1 -gt 1 ] && echo yes || echo no
yes
# -n 判断是否不会空 ! 非 组合起来就是 判断是否为空
[dayuanshuai@idys1 day6] [ ! -n $num ] && echo yes || echo no
no
注意:
!
”和-n
之间必须加入空格,否则会报错的。
if [ 条件判断式 ];then
程序
fi
if
语句使用 fi
结尾,和一般语言使用大括号结尾不同[ 条件判断式 ]
就是使用 test
命令判断,所以中括号和条件判断式之间必须有空格then
后面跟符合条件之后执行的程序,可以放在[]
之后,用;
分割。也可以换行写入, 就不需要;
了,比如单分支 if
语句还可以这样写:if [ 条件判断式 ]
then
程序
fi
10%
,那么就输出# awk 做法
# df -h 查看磁盘使用信息
# sed 去掉使用率前面的 %
# awk 进行判断
[dayuanshuai@idys1 day6] df -h | sed "s/%//g" | awk 'NR>1{if($5>10){printf("%-10s %i%\n",$1,$5)} }'
/dev/sda3 14%
/dev/sda1 20%
# 使用编程的做法
[dayuanshuai@idys1 day6] cat mytest.txt
#!/bin/bash
name=(`df -h | sed "1d" | awk '{print $1}'`)
value=(`df -h | sed "1d;s/%//g" | awk '{print $5}'`)
len=${#value[@]}
for((i=0;i<$len;i++));do
if [ ${value[$i]} -gt 10 ];then
echo "${name[$i]} used have more then 10%"
fi
done
if
条件语句if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
#!/bin/bash
function network_init(){
alter_file=$1
dns1=$4
dns2=$5
i=3
network_area=$2
gateway=$3
sed -i 's/^BOOTPROTO=.*$/BOOTPROTO="static"/g' $alter_file
sed -i 's/^ONBOOT=.*$/ONBOOT="yes"/g' $alter_file
# if grep -i "^IPADDR=.*" ./ifcfg-ens32;then
# sed -i "s/^IPADDR=.*/IPADDR=\"192.168.200.110\"/g" ./ifcfg-ens32
# else
# echo "IPADDR=\"192.168.200.110\"" >> ./ifcfg-ens32
# fi
while [ 1 ];do
if echo $network_area | grep -E "^(((\b[1-9]\b|\b[1-9][0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
1}((\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
2}(\b[0-9]{
1,2}\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]|\b|\b250))" >/dev/null 2>&1;then
break
else
echo -e "your input is error, please input again\n"
read -p $'请输入所属该网段的IP\n' network_area
fi
done
network_area_pre=`echo $network_area | sed -r "s/\.[[:digit:]]{1,3}$//g"`
if ping -c 1 $network_area > /dev/null 2>&1;then
while [ $i -le 254 ]
do
if ping -c 1 $network_area_pre.$i > /dev/null 2>&1;then
let i=i+1
else
if grep -i "^IPADDR=.*" $alter_file >/dev/null 2>&1;then
sed -i "s/^IPADDR=.*/IPADDR=\"192.168.200.$i\"/g" $alter_file
else
echo "IPADDR=\"192.168.200.$i\"" >> $alter_file
fi
break
fi
done
else
sed -i "s/^IPADDR=.*/IPADDR=\"$network_area\"/g" $alter_file
fi
if grep -i "^PREFIX=.*" $alter_file >/dev/null;then
sed -i "s/^PREFIX=.*/PREFIX=\"24\"/g" $alter_file
else
echo "PREFIX=\"24\"" >> $alter_file
fi
if grep -i "^GATEWAY=.*" $alter_file >/dev/null;then
sed -i "s/^GATEWAY=.*/GATEWAY=\"$gateway\"/g" $alter_file
else
echo "GATEWAY=\"$gateway\"" >> $alter_file
fi
if grep -i "^DNS1=.*" $alter_file > /dev/null;then
sed -i "s/^DNS1=.*/DNS1=\"$dns1\"/g" $alter_file
else
echo "DNS1=\"$dns1\"" >> $alter_file
fi
if grep -i "^DNS2=.*" $alter_file > /dev/null;then
sed -i "s/^DNS2=.*/DNS2=\"$dns2\"/g" $alter_file
else
echo "DNS2=\"$dns2\"" >> $alter_file
fi
}
function input_pra(){
read -p "请输入IP地址" ipaddr
while [ 1 ];do
if echo $ipaddr | grep -E "^(((\b[1-9]\b|\b[1-9][0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
1}((\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
2}(\b[0-9]{
1,2}\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]|\b|\b250))" >/dev/null 2>&1;then
break
else
echo -e "your input is error, please input again\n"
read -p $'请输入所属该网段的IP\n' ipaddr
fi
done
read -p "请输入网关地址" gateway
while [ 1 ];do
gateway_head=`echo $gateway | grep -Eo "(([[:digit:]]*)\.)*"`
ipaddr_head=`echo $ipaddr | grep -Eo "(([[:digit:]]*)\.)*"`
if echo $gateway | grep -E "^(((\b[1-9]\b|\b[1-9][0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
1}((\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
2}(\b[0-9]{
1,2}\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]|\b|\b250))" >/dev/null 2>&1;then
if [ $gateway_head == $ipaddr_head ];then
break
else
echo -e "your input is error, please input again\n"
read -p $'请输入网关地址\n' gateway
fi
else
echo -e "your input is error, please input again\n"
read -p $'请输入网关地址\n' gateway
fi
done
read -p "请输入DNS1" dns1
while [ 1 ];do
if echo $dns1 | grep -E "^(((\b[1-9]\b|\b[1-9][0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
1}((\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
2}(\b[0-9]{
1,2}\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]|\b|\b250))" >/dev/null 2>&1;then
break
else
echo -e "your input is error, please input again\n"
read -p $'请输入DNS1\n' dns1
fi
done
read -p "请输入DNS2" dns2
while [ 1 ];do
if echo $dns2 | grep -E "^(((\b[1-9]\b|\b[1-9][0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
1}((\b[1-9]\b|\b[1-9]?[0-9]\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]\b|\b25[0-5]\b)\.){
2}(\b[0-9]{
1,2}\b|\b1[0-9]{
2}\b|\b2[0-4][0-9]|\b|\b250))" >/dev/null 2>&1;then
break
else
echo -e "your input is error, please input again\n"
read -p $'请输入DNS2\n' dns2
fi
done
network_init "./ifcfg-ens32" $ipaddr $gateway $dns1 $dns2
}
input_pra
#!/bin/bash
#备份 mysql 数据库。
ntpdate asia.pool.ntp.org &>/dev/null
#同步系统时间
date=$(date +%y%m%d)
#把当前系统时间按照“年月日”格式赋予变量 date
size=$(du -sh /var/lib/mysql)
#统计 mysql 数据库的大小,并把大小赋予 size 变量
if [ -d /tmp/dbbak ]
#判断备份目录是否存在,是否为目录
then
#如果判断为真,执行以下脚本
echo "Date : $date!" > /tmp/dbbak/dbinfo.txt
#把当前日期写入临时文件
echo "Data size : $size" >> /tmp/dbbak/dbinfo.txt
#把数据库大小写入临时文件
cd /tmp/dbbak
#进入备份目录
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
#打包压缩数据库与临时文件,把所有输出丢入垃圾箱(不想看到任何输出)
rm -rf /tmp/dbbak/dbinfo.txt
#删除临时文件
else
mkdir /tmp/dbbak
#如果判断为假,则建立备份目录
echo "Date : $date!" > /tmp/dbbak/dbinfo.txt
echo "Data size : $size" >> /tmp/dbbak/dbinfo.txt
#把日期和数据库大小保存如临时文件
cd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz dbinfo.txt /var/lib/mysql &>/dev/null
#压缩备份数据库与临时文件
rm -rf /tmp/dbbak/dbinfo.txt
#删除临时文件
fi
apache
服务来举例:#!/bin/bash
#判断 apache 是否启动,如果没有启动则自动启动
port=$(nmap -sT 192.168.4.210 | grep tcp | grep http | awk '{print $2}')
#使用 nmap 命令扫描服务器,并截取 apache 服务的状态,赋予变量 port
if [ "$port" == "open" ]
#如果变量 port 的值是“open”
then
echo “$(date) httpd is ok!” >> /tmp/autostart-acc.log
#则证明 apache 正常启动,在正常日志中写入一句话即可
else
/etc/rc.d/init.d/httpd start &>/dev/null
#否则证明 apache 没有启动,自动启动 apache
echo "$(date) restart httpd !!" >> /tmp/autostart-err.log
#并在错误日志中记录自动启动 apche 的时间
fi
nmap
命令的使用nmap [Scan Type...] [Options] {target specification}
选项 | 含义 |
---|---|
-s |
扫描 |
-T |
扫描所有开启的 TCP 端口 |
-v |
显示详细信息 |
-p(rang) ,如-p20-120 定义扫描的端口为20 到120 ,-p23,80 :扫描23 和80 端口 |
自定义端口范围 |
-sP |
nmap 可以利用类似windows/linux 系统下的ping 方式进行扫描 |
--traceroute |
路由器追踪功能 |
[root@idys ~] nmap -sT baidu.com
Starting Nmap 6.40 ( http://nmap.org ) at 2020-08-25 11:23 CST
Nmap scan report for baidu.com (39.156.69.79)
Host is up (0.036s latency).
Not shown: 996 filtered ports
PORT STATE SERVICE
25/tcp open smtp
80/tcp open http
110/tcp open pop3
443/tcp open https
# 查看 http端口是否开发
[root@idys ~] nmap -sT 120.79.167.129 | grep http | awk '{print $2}'
Nmap
open
if
条件语句if [ 条件判断式 1 ]
then
当条件判断式 1 成立时,执行程序 1
elif [ 条件判断式 2 ]
then
当条件判断式 2 成立时,执行程序 2
…省略更多条件…
else
当所有条件都不成立时,最后执行此程序
fi
find
用 扩展正则表达式-regextype 'posix-egrep' -regex '扩展正则表达式'
sleep
number
: 时间长度,后面可接 s
、m
、h
或 d
s
为秒,m
为 分钟,h
为小时,d
为日数# 暂停 4s 钟表
[root@idys ~] sleep 4
[root@idys ~]
# 暂停 4 分钟
[root@idys ~] sleep 4m
# 实现加载 效果
[root@idys ~] for((i=0;i<4;i++));do echo -n ".";sleep 1;done;echo ""
....
paste
-d
:指定分隔符-s
:多行变为一行,以每个文件为一个处理单元[dayuanshuai@idys day03_sh] cat a.txt
1
2
3
4
5
6
7
8
9
10
[dayuanshuai@idys day03_sh] cat b.txt
a
b
c
d
e
f
g
h
i
j
[dayuanshuai@idys day03_sh] cat c.txt
11
12
13
14
15
16
17
18
19
20
[dayuanshuai@idys day03_sh] paste a.txt b.txt c.txt
1 a 11
2 b 12
3 c 13
4 d 14
5 e 15
6 f 16
7 g 17
8 h 18
9 i 19
10 j 20
# 多行变为一行,以 \t 分隔
[dayuanshuai@idys day03_sh] paste -s a.txt
1 2 3 4 5 6 7 8 9 10
[dayuanshuai@idys day03_sh] paste -s a.txt b.txt
1 2 3 4 5 6 7 8 9 10
a b c d e f g h i j
[dayuanshuai@idys day03_sh] paste -s a.txt b.txt c.txt
1 2 3 4 5 6 7 8 9 10
a b c d e f g h i j
11 12 13 14 15 16 17 18 19 20
[dayuanshuai@idys day03_sh] paste -d '-' -s a.txt
1-2-3-4-5-6-7-8-9-10
[dayuanshuai@idys day03_sh] paste -d '-' a.txt b.txt
1-a
2-b
3-c
4-d
5-e
6-f
7-g
8-h
9-i
10-j
[dayuanshuai@idys day03_sh] paste -d '-' -s a.txt b.txt
1-2-3-4-5-6-7-8-9-10
a-b-c-d-e-f-g-h-i-j
tr
命令:用于转换或删除文件中的字符tr [-cdst][--help][--version][第一字符集][第二字符集]
tr [OPTION]…SET1[SET2]
-c
, --complement
:反选设定字符。也就是符合 SET1
的部份不做处理,不符合的剩余部份才进行转换-d
, --delete
:删除指令字符-s
, --squeeze-repeats
:缩减连续重复的字符成指定的单个字符-t
, --truncate-set1
:削减 SET1
指定范围,使之与 SET2
设定长度相等--help
:显示程序用法信息--version
:显示程序本身的版本信息字符集合的范围:
\NNN
八进制值的字符 NNN
(1to 3
为八进制值的字符)\\
反斜杠\a Ctrl-G
铃声\b Ctrl-H
退格符\f Ctrl-L
走行换页\n Ctrl-J
新行\r Ctrl-M
回车\t Ctrl-I tab
键\v Ctrl-X
水平制表符CHAR1-CHAR2
:字符范围从 CHAR1
到 CHAR2
的指定,范围的指定以 ASCII 码的次序为基础,只能由小到大,不能由大到小。[CHAR*]
:这是 SET2
专用的设定,功能是重复指定的字符到与 SET1
相同长度为止[CHAR*REPEAT]
:这也是 SET2
专用的设定,功能是重复指定的字符到设定的 REPEAT 次数为止(REPEAT 的数字采 8 进位制计算,以 0 为开始)[:alnum:]
:所有字母字符与数字[:alpha:]
:所有字母字符[:blank:]
:所有水平空格[:cntrl:]
:所有控制字符[:digit:]
:所有数字[:graph:]
:所有可打印的字符(不包含空格符)[:lower:]
:所有小写字母[:print:]
:所有可打印的字符(包含空格符)[:punct:]
:所有标点字符[:space:]
:所有水平与垂直空格符[:upper:]
:所有大写字母[:xdigit:]
:所有 16
进位制的数字[=CHAR=]
:所有符合指定的字符(等号里的CHAR
,代表你可自订的字符)tr
实现将小写字母替换为大写字母[dayuanshuai@idys day03_sh] cat mytext.txt
how are you
please
thank you
me me and you
ok ok haha
H W o kw
HOW br br br PO PO PO
ksks W l LS nj
[dayuanshuai@idys day03_sh] cat mytext.txt | tr "a-z" "A-Z"
HOW ARE YOU
PLEASE
THANK YOU
ME ME AND YOU
OK OK HAHA
H W O KW
HOW BR BR BR PO PO PO
KSKS W L LS NJ
[dayuanshuai@idys day03_sh] cat mytext.txt | tr [:lower:] [:upper:]
HOW ARE YOU
PLEASE
THANK YOU
ME ME AND YOU
OK OK HAHA
H W O KW
HOW BR BR BR PO PO PO
KSKS W L LS NJ
[dayuanshuai@idys day03_sh] cat mytext.txt
how 10 are you
12 please
thank 3 you
me me 2 and you
ok ok 2 haha 1
H W 78 12 o kw 189
HOW br 56 12 br br PO PO PO
ksks 12 W l LS nj
# 删除文本里面的数字
[dayuanshuai@idys day03_sh] cat mytext.txt | tr -d '0-9'
how are you
please
thank you
me me and you
ok ok haha
H W o kw
HOW br br br PO PO PO
ksks W l LS nj
# 将空格转化为 制表符
[dayuanshuai@idys day03_sh] cat mytext.txt | tr " " "\t"
how 10 are you
12 please
thank 3 you
me me 2 and you
ok ok 2 haha 1
H W 78 12 o kw 189
HOW br 56 12 br br PO PO PO
ksks 12 W l LS nj
# 反选匹配到的字符, 如果匹配到的字符 就不做处理。 没有匹配到的字符就处理 -d 是删除的意思
[dayuanshuai@idys day03_sh] cat mytext.txt | tr -d -c "1-9 \n how"
how 1 o
12
h 3 o
2 o
o o 2 hh 1
78 12 o w 189
56 12
12
[dayuanshuai@idys day03_sh] cat mytext.txt
how 10 are you
12 please
thank 3 you
me me 2 and you
ok ok 2 haha 1
H W 78 12 o kw 189
HOW br 56 12 br br PO PO PO
ksks 12 W l LS nj
who wwwwwww sssss
bbbbbb kkkkk qqqqq ooooo sssss vvvv
# 删减重复的字符 ,字符里面包括 b k q o s w v
[dayuanshuai@idys day03_sh] cat mytext.txt | tr -s "b k q o s w v"
how 10 are you
12 please
thank 3 you
me me 2 and you
ok ok 2 haha 1
H W 78 12 o kw 189
HOW br 56 12 br br PO PO PO
ksks 12 W l LS nj
who w s
b k q o s v
[dayuanshuai@idys ~] seq 6 12
6
7
8
9
10
11
12
[dayuanshuai@idys ~] seq 6 12
6
7
8
9
10
11
12
# tr 命令 实现数字加减
[dayuanshuai@idys ~] seq 6 12 | echo $[ $(tr "\n" "+")0 ]
63
# 生产固定长度的随机数密码
[dayuanshuai@idys day03_sh] head /dev/urandom | tr -dc A-Za-z0-9 | head -c 20;echo ""
0fUqCj7GXHaiYuAXENGM
if
多分支条件语句演示,查找所有的压缩文件,并且按照编号对压缩文件进行编号。同时选择某个编号的时候,可以打印出编号对应的压缩文件#!/bin/bash
function my_select(){
array=(`find / -type f -iname "*.tar" -o -iname "*.zip" -o -name "*.rar" -o -iname "*.gzip" -o -iname "*.iso" -o -iname "*.tar.gz" -o -iname "*.gz" `) # you can select command find or locate, command locate is efficient, but it is inaccurate. so I select command find.
while [ 1 ];do
read -p "first, the program be display is similar to less,when you read , you used comamnd as less, if you know [Y/N]" judge
if [ $judge == "Y" -o $judge == "y" ];then
break
fi
done
while [ 1 ];do for i in ${!array[@]};do printf "%-6i -------------------> %-50s\n" $((i+1)) ${array[$i]};done | less ;read -p $'please input num to choice file \n ---------->' num;if [ -z $num ];then echo -e "because you input is null, the system is default choice\n-----------------> ${array[0]}";break;elif echo $num | grep -E '[^[:digit:]]';then echo -e "yur input is contain other char,please input again";echo -e "because your input is error, please wait 10 second \n";for((i=0;i<10;i++));do echo -n "* ";sleep 1;done;echo -e "\n";elif [ $num -gt ${#array[@]} ];then echo -e "\nyou input num more than the total of compressed file,the operation is error\n";echo -e "because your input is error, please wait 10second\n";for((i=0;i<10;i++));do echo -n "* ";sleep 1;done;echo -e "\n";else echo "your choice file is ----------------> ${array[$((num-1))]}";break;fi;done
}
my_select
# 第一次 测试
[root@idys ~] bash mytest.sh
first, the program be display is similar to less,when you read , you used comamnd as less, if you know [Y/N]Y
1 -------------------> /boot/grub/splash.xpm.gz
2 -------------------> /boot/symvers-3.10.0-1062.el7.x86_64.gz
3 -------------------> /root/testnet.sh.gz
4 -------------------> /var/cache/yum/x86_64/7/base/a4e2b46586aa556c3b6f814dad5b16db5a669984d66b68e873586cd7c7253301-c7-x86_64-comps.xml.gz
5 -------------------> /var/cache/yum/x86_64/7/c7-media/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
6 -------------------> /var/cache/yum/x86_64/7/CentOS7/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
7 -------------------> /tmp/day01_sh.tar
8 -------------------> /usr/lib/kbd/consolefonts/gr928a-8x16.psfu.gz
9 -------------------> /usr/lib/kbd/consolefonts/161.cp.gz
10 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x14.psfu.gz
11 -------------------> /usr/lib/kbd/consolefonts/162.cp.gz
12 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x16.psfu.gz
13 -------------------> /usr/lib/kbd/consolefonts/163.cp.gz
14 -------------------> /usr/lib/kbd/consolefonts/iso01-12x22.psfu.gz
15 -------------------> /usr/lib/kbd/consolefonts/164.cp.gz
16 -------------------> /usr/lib/kbd/consolefonts/iso01.14.gz
17 -------------------> /usr/lib/kbd/consolefonts/165.cp.gz
18 -------------------> /usr/lib/kbd/consolefonts/iso01.08.gz
19 -------------------> /usr/lib/kbd/consolefonts/737.cp.gz
20 -------------------> /usr/lib/kbd/consolefonts/iso01.16.gz
21 -------------------> /usr/lib/kbd/consolefonts/880.cp.gz
22 -------------------> /usr/lib/kbd/consolefonts/iso02.14.gz
23 -------------------> /usr/lib/kbd/consolefonts/928.cp.gz
24 -------------------> /usr/lib/kbd/consolefonts/iso02-12x22.psfu.gz
25 -------------------> /usr/lib/kbd/consolefonts/972.cp.gz
26 -------------------> /usr/lib/kbd/consolefonts/cybercafe.fnt.gz
27 -------------------> /usr/lib/kbd/consolefonts/Agafari-12.psfu.gz
28 -------------------> /usr/lib/kbd/consolefonts/cyr-sun16.psfu.gz
29 -------------------> /usr/lib/kbd/consolefonts/Agafari-14.psfu.gz
30 -------------------> /usr/lib/kbd/consolefonts/default8x16.psfu.gz
31 -------------------> /usr/lib/kbd/consolefonts/Agafari-16.psfu.gz
32 -------------------> /usr/lib/kbd/consolefonts/default8x9.psfu.gz
33 -------------------> /usr/lib/kbd/consolefonts/Cyr_a8x14.psfu.gz
34 -------------------> /usr/lib/kbd/consolefonts/drdos8x14.psfu.gz
35 -------------------> /usr/lib/kbd/consolefonts/Cyr_a8x16.psfu.gz
36 -------------------> /usr/lib/kbd/consolefonts/drdos8x16.psfu.gz
37 -------------------> /usr/lib/kbd/consolefonts/Cyr_a8x8.psfu.gz
38 -------------------> /usr/lib/kbd/consolefonts/iso02.08.gz
39 -------------------> /usr/lib/kbd/consolefonts/drdos8x6.psfu.gz
40 -------------------> /usr/lib/kbd/consolefonts/Goha-12.psfu.gz
41 -------------------> /usr/lib/kbd/consolefonts/drdos8x8.psfu.gz
42 -------------------> /usr/lib/kbd/consolefonts/Goha-14.psfu.gz
43 -------------------> /usr/lib/kbd/consolefonts/eurlatgr.psfu.gz
44 -------------------> /usr/lib/kbd/consolefonts/Goha-16.psfu.gz
45 -------------------> /usr/lib/kbd/consolefonts/UniCyr_8x16.psf.gz
46 -------------------> /usr/lib/kbd/consolefonts/GohaClassic-12.psfu.gz
47 -------------------> /usr/lib/kbd/consolefonts/UniCyr_8x8.psf.gz
48 -------------------> /usr/lib/kbd/consolefonts/GohaClassic-14.psfu.gz
49 -------------------> /usr/lib/kbd/consolefonts/alt-8x14.gz
50 -------------------> /usr/lib/kbd/consolefonts/iso05.08.gz
51 -------------------> /usr/lib/kbd/consolefonts/GohaClassic-16.psfu.gz
52 -------------------> /usr/lib/kbd/consolefonts/alt-8x16.gz
53 -------------------> /usr/lib/kbd/consolefonts/iso05.14.gz
54 -------------------> /usr/lib/kbd/consolefonts/Lat2-Terminus16.psfu.gz
55 -------------------> /usr/lib/kbd/consolefonts/alt-8x8.gz
56 -------------------> /usr/lib/kbd/consolefonts/iso05.16.gz
57 -------------------> /usr/lib/kbd/consolefonts/LatArCyrHeb-08.psfu.gz
58 -------------------> /usr/lib/kbd/consolefonts/aply16.psf.gz
59 -------------------> /usr/lib/kbd/consolefonts/LatArCyrHeb-14.psfu.gz
60 -------------------> /usr/lib/kbd/consolefonts/altc-8x16.gz
61 -------------------> /usr/lib/kbd/consolefonts/iso06.08.gz
62 -------------------> /usr/lib/kbd/consolefonts/LatArCyrHeb-16+.psfu.gz
63 -------------------> /usr/lib/kbd/consolefonts/arm8.fnt.gz
64 -------------------> /usr/lib/kbd/consolefonts/iso06.14.gz
65 -------------------> /usr/lib/kbd/consolefonts/LatArCyrHeb-16.psfu.gz
66 -------------------> /usr/lib/kbd/consolefonts/cp1250.psfu.gz
67 -------------------> /usr/lib/kbd/consolefonts/LatArCyrHeb-19.psfu.gz
68 -------------------> /usr/lib/kbd/consolefonts/cp850-8x14.psfu.gz
69 -------------------> /usr/lib/kbd/consolefonts/LatGrkCyr-12x22.psfu.gz
70 -------------------> /usr/lib/kbd/consolefonts/cp850-8x16.psfu.gz
71 -------------------> /usr/lib/kbd/consolefonts/LatGrkCyr-8x16.psfu.gz
72 -------------------> /usr/lib/kbd/consolefonts/gr737b-9x16-medieval.psfu.gz
73 -------------------> /usr/lib/kbd/consolefonts/LatKaCyrHeb-14.psfu.gz
74 -------------------> /usr/lib/kbd/consolefonts/iso02.16.gz
please input num to choice file
---------->45
your choice file is ----------------> /usr/lib/kbd/consolefonts/UniCyr_8x16.psf.gz
# 第二次测试
[root@idys ~] bash mytest.sh
first, the program be display is similar to less,when you read , you used comamnd as less, if you know [Y/N]Y
1 -------------------> /boot/grub/splash.xpm.gz
2 -------------------> /boot/symvers-3.10.0-1062.el7.x86_64.gz
3 -------------------> /root/testnet.sh.gz
4 -------------------> /var/cache/yum/x86_64/7/base/a4e2b46586aa556c3b6f814dad5b16db5a669984d66b68e873586cd7c7253301-c7-x86_64-comps.xml.gz
5 -------------------> /var/cache/yum/x86_64/7/c7-media/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
6 -------------------> /var/cache/yum/x86_64/7/CentOS7/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
7 -------------------> /tmp/day01_sh.tar
8 -------------------> /usr/lib/kbd/consolefonts/gr928a-8x16.psfu.gz
9 -------------------> /usr/lib/kbd/consolefonts/161.cp.gz
10 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x14.psfu.gz
11 -------------------> /usr/lib/kbd/consolefonts/162.cp.gz
12 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x16.psfu.gz
13 -------------------> /usr/lib/kbd/consolefonts/163.cp.gz
14 -------------------> /usr/lib/kbd/consolefonts/iso01-12x22.psfu.gz
15 -------------------> /usr/lib/kbd/consolefonts/164.cp.gz
16 -------------------> /usr/lib/kbd/consolefonts/iso01.14.gz
17 -------------------> /usr/lib/kbd/consolefonts/165.cp.gz
18 -------------------> /usr/lib/kbd/consolefonts/iso01.08.gz
19 -------------------> /usr/lib/kbd/consolefonts/737.cp.gz
20 -------------------> /usr/lib/kbd/consolefonts/iso01.16.gz
21 -------------------> /usr/lib/kbd/consolefonts/880.cp.gz
22 -------------------> /usr/lib/kbd/consolefonts/iso02.14.gz
23 -------------------> /usr/lib/kbd/consolefonts/928.cp.gz
24 -------------------> /usr/lib/kbd/consolefonts/iso02-12x22.psfu.gz
25 -------------------> /usr/lib/kbd/consolefonts/972.cp.gz
26 -------------------> /usr/lib/kbd/consolefonts/cybercafe.fnt.gz
27 -------------------> /usr/lib/kbd/consolefonts/Agafari-12.psfu.gz
28 -------------------> /usr/lib/kbd/consolefonts/cyr-sun16.psfu.gz
29 -------------------> /usr/lib/kbd/consolefonts/Agafari-14.psfu.gz
30 -------------------> /usr/lib/kbd/consolefonts/default8x16.psfu.gz
please input num to choice file
---------->1000000
you input num more than the total of compressed file,the operation is error
because your input is error, please wait 10second
* * * * * * * * * *
1 -------------------> /boot/grub/splash.xpm.gz
2 -------------------> /boot/symvers-3.10.0-1062.el7.x86_64.gz
3 -------------------> /root/testnet.sh.gz
4 -------------------> /var/cache/yum/x86_64/7/base/a4e2b46586aa556c3b6f814dad5b16db5a669984d66b68e873586cd7c7253301-c7-x86_64-comps.xml.gz
5 -------------------> /var/cache/yum/x86_64/7/c7-media/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
6 -------------------> /var/cache/yum/x86_64/7/CentOS7/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
7 -------------------> /tmp/day01_sh.tar
8 -------------------> /usr/lib/kbd/consolefonts/gr928a-8x16.psfu.gz
9 -------------------> /usr/lib/kbd/consolefonts/161.cp.gz
10 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x14.psfu.gz
11 -------------------> /usr/lib/kbd/consolefonts/162.cp.gz
12 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x16.psfu.gz
13 -------------------> /usr/lib/kbd/consolefonts/163.cp.gz
14 -------------------> /usr/lib/kbd/consolefonts/iso01-12x22.psfu.gz
15 -------------------> /usr/lib/kbd/consolefonts/164.cp.gz
16 -------------------> /usr/lib/kbd/consolefonts/iso01.14.gz
17 -------------------> /usr/lib/kbd/consolefonts/165.cp.gz
18 -------------------> /usr/lib/kbd/consolefonts/iso01.08.gz
19 -------------------> /usr/lib/kbd/consolefonts/737.cp.gz
20 -------------------> /usr/lib/kbd/consolefonts/iso01.16.gz
please input num to choice file
---------->sdfsdf
sdfsdf
yur input is contain other char,please input again
because your input is error, please wait 10 second
* * * * * * * * * *
1 -------------------> /boot/grub/splash.xpm.gz
2 -------------------> /boot/symvers-3.10.0-1062.el7.x86_64.gz
3 -------------------> /root/testnet.sh.gz
4 -------------------> /var/cache/yum/x86_64/7/base/a4e2b46586aa556c3b6f814dad5b16db5a669984d66b68e873586cd7c7253301-c7-x86_64-comps.xml.gz
5 -------------------> /var/cache/yum/x86_64/7/c7-media/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
6 -------------------> /var/cache/yum/x86_64/7/CentOS7/4af1fba0c1d6175b7e3c862b4bddfef93fffb84c37f7d5f18cfbff08abc47f8a-c7-x86_64-comps.xml.gz
7 -------------------> /tmp/day01_sh.tar
8 -------------------> /usr/lib/kbd/consolefonts/gr928a-8x16.psfu.gz
9 -------------------> /usr/lib/kbd/consolefonts/161.cp.gz
10 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x14.psfu.gz
11 -------------------> /usr/lib/kbd/consolefonts/162.cp.gz
12 -------------------> /usr/lib/kbd/consolefonts/gr928b-8x16.psfu.gz
13 -------------------> /usr/lib/kbd/consolefonts/163.cp.gz
14 -------------------> /usr/lib/kbd/consolefonts/iso01-12x22.psfu.gz
15 -------------------> /usr/lib/kbd/consolefonts/164.cp.gz
16 -------------------> /usr/lib/kbd/consolefonts/iso01.14.gz
17 -------------------> /usr/lib/kbd/consolefonts/165.cp.gz
18 -------------------> /usr/lib/kbd/consolefonts/iso01.08.gz
19 -------------------> /usr/lib/kbd/consolefonts/737.cp.gz
20 -------------------> /usr/lib/kbd/consolefonts/iso01.16.gz
21 -------------------> /usr/lib/kbd/consolefonts/880.cp.gz
22 -------------------> /usr/lib/kbd/consolefonts/iso02.14.gz
23 -------------------> /usr/lib/kbd/consolefonts/928.cp.gz
24 -------------------> /usr/lib/kbd/consolefonts/iso02-12x22.psfu.gz
25 -------------------> /usr/lib/kbd/consolefonts/972.cp.gz
26 -------------------> /usr/lib/kbd/consolefonts/cybercafe.fnt.gz
27 -------------------> /usr/lib/kbd/consolefonts/Agafari-12.psfu.gz
28 -------------------> /usr/lib/kbd/consolefonts/cyr-sun16.psfu.gz
29 -------------------> /usr/lib/kbd/consolefonts/Agafari-14.psfu.gz
30 -------------------> /usr/lib/kbd/consolefonts/default8x16.psfu.gz
31 -------------------> /usr/lib/kbd/consolefonts/Agafari-16.psfu.gz
32 -------------------> /usr/lib/kbd/consolefonts/default8x9.psfu.gz
please input num to choice file
---------->12
your choice file is ----------------> /usr/lib/kbd/consolefonts/gr928b-8x16.psfu.gz
#!/bin/bash
# 判断用户输入的是什么文件
read -p "Please input a filename: " file
#接收键盘的输入,并赋予变量 file
if [ -z "$file" ]
#判断 file 变量是否为空
then
echo "Error,please input a filename"
#如果为空,执行程序 1,也就是输出报错信息
exit 1
#退出程序,并返回值为 1(把返回值赋予变量$?)
elif [ ! -e "$file" ]
#判断 file 的值是否存在
then
echo "Your input is not a file!"
#如果不存在,则执行程序 2
exit 2
#退出程序,把并定义返回值为 2
elif [ -f "$file" ]
#判断 file 的值是否为普通文件
then
echo "$file is a regulare file!"
#如果是普通文件,则执行程序 3
elif [ -d "$file" ]
#判断 file 的值是否为目录文件
then
echo "$file is a directory!"
#如果是目录文件,则执行程序 4
else
echo "$file is an other file!"
#如果以上判断都不是,则执行程序 5
fi
case
语句和 if…elif…else
语句一样都是多分支条件语句,不过和 if
多分支条件语句不同的是, case
语句只能判断一种条件关系,而 if 语句可以判断多种条件关系。case
语句语法如下case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
这个语句需要注意以下内容:
case
语句,会取出变量中的值,然后与语句体中的值逐一比较。如果数值符合,则执行对应的程序,如果数值不符,则依次比较下一个值。如果所有的值都不符合,则执行*)
(*
代表所有其他值)中的程序case
语句以case
开头,以esac
结尾。每一个分支程序之后要通过;;
双分号结尾,代表该程序段结束
case
语句综合应用
[dayuanshuai@idys day03_sh] cat system_menu.sh
#!/bin/bash
function display_ip(){
ifconfig | grep "inet" | head -1| awk '{print $2}'
}
function display_disk(){
df -h | awk 'NR>=2{ printf "%-10s --------> %s\n",$1,$5 }'
}
function system_run(){
uptime | awk -F '[ :,]' '{printf "your system have run %i hour %i minute\n",$6,$7}'
}
function system_display(){
cat << EOF
----------------------------------------
|*****************Menu******************|
----------------------------------------
`echo -e "\033[31m 1)display the left of disk space\033[0m"`
`echo -e "\033[32m 2)display IP address\033[0m"`
`echo -e "\033[33m 3)display system have run time\033[0m"`
EOF
read -p $'please input your num\n' num
case $num in
1)
display_disk
;;
2)
display_ip
;;
3)
system_run
;;
*)
system_display
esac
}
system_display
[dayuanshuai@idys day03_sh] bash system_menu.sh
----------------------------------------
|*****************Menu******************|
----------------------------------------
1)display the left of disk space
2)display IP address
3)display system have run time
please input your num
2
192.168.200.143
[dayuanshuai@idys day03_sh] bash system_menu.sh
----------------------------------------
|*****************Menu******************|
----------------------------------------
1)display the left of disk space
2)display IP address
3)display system have run time
please input your num
3
your system have run 13 hour 39 minute
[dayuanshuai@idys day03_sh] bash system_menu.sh
----------------------------------------
|*****************Menu******************|
----------------------------------------
1)display the left of disk space
2)display IP address
3)display system have run time
please input your num
1
devtmpfs --------> 0%
tmpfs --------> 0%
tmpfs --------> 1%
tmpfs --------> 0%
/dev/sda2 --------> 6%
/dev/sr0 --------> 100%
/dev/sda1 --------> 56%
tmpfs --------> 0%
tmpfs --------> 0%
#!/bin/bash
#判断用户输入
read -p "Please choose yes/no: " -t 30 cho
#在屏幕上输出“请选择 yes/no”,然后把用户选择赋予变量 cho
case $cho in
#判断变量 cho 的值
"yes")
#如果是 yes
echo "Your choose is yes!"
#执行程序 1
;;
"no")
#如果是 no
echo "Your choose is no!"
#执行程序 2
;;
*)
#如果既不是 yes,也不是 no
echo "Your choose is error!"
#则执行此程序
;;
esac
for
循环是固定循环,也就是在循环时已经知道需要进行几次的循环,有时也把 for
循环称为计数循环。for
的语法有如下两种:
语言一:
for 变量 in 值 1 值 2 值 3…
do
程序
done
for
循环的次数,取决于 in
后面值的个数(空格分隔),有几个值就循环几次,并且每次循环都把值赋予变量。也就是说,假设 in
后面有三个值,for
会循环三次,第一次循环会把值 1
赋予变量,第二次循环会把值 2
赋予变量,以此类推。for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
i=1
;i<=100
,则只要 i
的值小于等于 100
,循环就会继续;i=i+1
。代表每次循环之后,变量 i
的值都 加 1
[root@idys ~]# for i in 1 2 3;do echo $i;done;
1
2
3
[dayuanshuai@idys day01_sh]$ cat for_one_type.sh
# !/bin/bash
for i in 1 2 3
do
echo $i
done
[dayuanshuai@idys day01_sh]$ chmod u+x for_one_type.sh
[dayuanshuai@idys day01_sh]$ ./for_one_type.sh
1
2
3
[root@idys LAMP-php7] ls | tr " " "\n" | xargs -n1 -I {
} tar -zxvf {
}
[root@idys LAMP-php7] ls ./*.gz | xargs -n 1 -I {
} rm {
}
*.gz
,*zip
的文件[root@idys LAMP-php7] ls # 当前目录下有目录文件和压缩文件
apr-1.4.6 jpegsrc.v6b.tar.gz memcached-1.4.17 pcre-8.34.tar.gz
apr-1.4.6.tar.gz libmcrypt-2.5.8 memcached-1.4.17.tar.gz pecl-memcache-php7.zip
apr-util-1.4.1 libmcrypt-2.5.8.tar.gz mhash-0.9.9.9 php-7.0.7
apr-util-1.4.1.tar.gz libpng-1.2.31 mhash-0.9.9.9.tar.gz php-7.0.7.tar.gz
freetype-2.3.5 libpng-1.2.31.tar.gz mysql-5.5.48 phpMyAdmin-4.1.4-all-languages
freetype-2.3.5.tar.gz libxml2-2.9.1 mysql-5.5.48.tar.gz phpMyAdmin-4.1.4-all-languages.tar.gz
httpd-2.4.7 libxml2-2.9.1.tar.gz ncurses-5.9 zlib-1.2.3
httpd-2.4.7.tar.gz mcrypt-2.6.8 ncurses-5.9.tar.gz zlib-1.2.3.tar.gz
jpeg-6b mcrypt-2.6.8.tar.gz pcre-8.34
[root@idys LAMP-php7] ls --ignore="*.gz" --ignore="*.zip" | xargs -n1 -I {
} rm -rf {
} # 现在删除当前目录下所有的目录文件
[root@idys LAMP-php7] ls
apr-1.4.6.tar.gz libmcrypt-2.5.8.tar.gz mhash-0.9.9.9.tar.gz php-7.0.7.tar.gz
apr-util-1.4.1.tar.gz libpng-1.2.31.tar.gz mysql-5.5.48.tar.gz phpMyAdmin-4.1.4-all-languages.tar.gz
freetype-2.3.5.tar.gz libxml2-2.9.1.tar.gz ncurses-5.9.tar.gz zlib-1.2.3.tar.gz
httpd-2.4.7.tar.gz mcrypt-2.6.8.tar.gz pcre-8.34.tar.gz
jpegsrc.v6b.tar.gz memcached-1.4.17.tar.gz pecl-memcache-php7.zip
# 首先查看当前目录下的所有文件(含目录)
[root@idys LAMP-php7] ls
apr-1.4.6.tar.gz libmcrypt-2.5.8.tar.gz mhash-0.9.9.9.tar.gz php-7.0.7.tar.gz
apr-util-1.4.1.tar.gz libpng-1.2.31.tar.gz mysql-5.5.48.tar.gz phpMyAdmin-4.1.4-all-languages.tar.gz
freetype-2.3.5.tar.gz libxml2-2.9.1.tar.gz ncurses-5.9.tar.gz zlib-1.2.3.tar.gz
httpd-2.4.7.tar.gz mcrypt-2.6.8.tar.gz pcre-8.34.tar.gz
jpegsrc.v6b.tar.gz memcached-1.4.17.tar.gz pecl-memcache-php7.zip
# 解压所有的压缩文件,并且不输出,最后echo $? 查看返回结果
[root@idys LAMP-php7] for i in `ls *gz`;do tar -zxvf $i >/dev/null 2>&1;done;unzip *.zip &>/dev/null;echo $?
0
for
循环实现累加(1到100)[dayuanshuai@idys day01_sh] cat for_two_typev1.sh
# !/bin/bash
for((i=1;i<=100;i++))
do
let sum=sum+i
done
echo -n "sum="
for i in `seq 1 100`
do
if [ $i -ge 100 ];then
echo -n $i
else
echo -n "$i+"
fi
done
echo "=$sum"
[dayuanshuai@idys day01_sh] bash for_two_typev1.sh
sum=1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100=5050
[root@idys day01_sh] vim useradd_username.sh
#让用户输入初始密码,把输入保存如变量 pass
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]
fi
done
# !/bin/bash
function useradd_username(){
read -p "Please input user name: " -t 60 name
#让用户输入用户名,把输入保存入变量 name
read -p "Please input the number of users: " -t 60 num
#让用户输入添加用户的数量,把输入保存入变量 num
read -p "Please input the password of users: " -t 60 pass
#让用户输入初始密码,把输入保存如变量 pass
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ];then
if echo $num | grep "^[[:digit:]]$" >/dev/null 2>&1;then
for (( i=1;i<=$num;i=i+1 ))
#循环 num 变量指定的次数
do
/usr/sbin/useradd $name$i &>/dev/null
#添加用户,用户名为变量 name 的值加变量 i 的数字
echo $pass | /usr/bin/passwd --stdin $name$i &>/dev/null
#给用户设定初始密码为变量 pass 的值
done
fi
fi
}
useradd_username
[root@idys day01_sh] bash useradd_username.sh
Please input user name: idys
Please input the number of users: 4
Please input the password of users: 123456
[root@idys day01_sh] ls /home
dayuanshuai idys1 idys2 idys3 idys4
[root@idys day01_sh] su - dayuanshuai
上一次登录:日 9月 6 17:40:47 CST 2020pts/1 上
[dayuanshuai@idys ~] su - idys1
密码:
[idys1@idys ~] exit
登出
[root@idys day01_sh] ls /home
dayuanshuai idys1 idys2 idys3 idys4
[root@idys day01_sh] cat /etc/passwd | grep /bin/bash | grep -vE "root|dayuanshuai" | awk -F ":" '{printf $1"\n"}'
idys1
idys2
idys3
idys4
[root@idys day01_sh] cat /etc/passwd | grep /bin/bash | grep -vE "root|dayuanshuai" | awk -F ":" '{printf $1"\n"}' | xargs -n1 -I {
} userdel -r {
}
[root@idys day01_sh] ls /home # 现在可以看到所有的其他用户均删除了
dayuanshuai
[root@idys day01_sh] bash useradd_username.sh # 再次添加用户
Please input user name: hanhan
Please input the number of users: 5
Please input the password of users: 123456
[root@idys day01_sh] for i in `cat /etc/passwd | grep /bin/bash | grep -vE "root|dayuanshuai" | awk -F ":" '{printf $1"\n"}'`;do userdel -r $i;done #利用for循环删除其他用户
while
循环语法形式while [ 条件判断式 ]
do
程序
done
对 while 循环来讲,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。
while
循环,将一个数从1
输出到100
[dayuanshuai@idys day01_sh] cat while_file.sh
# !/bin/bash
function test_while(){
i=$1
k=0
while [ $i -le 100 ]
do
echo -ne "$i\t"
let i=i+1
let k=k+1
if [ $((k % 16)) -eq 0 ];then
echo ""
fi
done
echo ""
}
test_while 1
[dayuanshuai@idys day01_sh] bash while_file.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
97 98 99 100
until
循环,和 while
循环相反,until
循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。语法如下:until [ 条件判断式 ]
do
程序
done
1
加到 100
这个例子,注意和 while 循环的区别[dayuanshuai@idys day01_sh] cat until_while.sh
# !/bin/bash
function until_perform(){
i=0
until [ $i -gt 100 ]
do
let s=s+i
let i=i+1
done
echo $s
return $s
}
function print_num(){
s=`until_perform`
echo "the num is: $s"
}
print_num
function 函数名 () {
程序
}
0
累加到多少[dayuanshuai@idys day01_sh] cat functionv1.sh
# !/bin/bash
function add_num(){
for((i=0;i<=$1;i++))
do
let s=s+i
done
echo $s
}
function user_input(){
read -p "please input num to decide add to " num
if echo $num | grep -E "^[[:digit:]]*$" >/dev/null 2>&1;then
result=`add_num $num`
echo "the end of result is $result"
else
echo "your input is error, please input again, thank you"
fi
}
user_input
exit
命令的,用于退出当前用户的登录状态。可是在 Shell
脚本中,exit
语句是用来退出当前脚本的。也就是说,在 Shell
脚本中,只要碰到了 exit
语句,后续的程序就不再执行,而直接退出脚本。exit
的语法如下:exit [返回值]
exit
命令之后定义了返回值,那么这个脚本执行之后的返回值就是我们自己定义的返回值。 可以通过查询$?
这个变量,来查看返回值。如果 exit
之后没有定义返回值,脚本执行之后的返回值是执行 exit
语句之前,最后执行的一条命令的返回值。写一个 exit
的例子:[dayuanshuai@idys day01_sh] cat exit_num.sh
# !/bin/bash
function test_num(){
read -p "please input num" -t 60 num
num_second=`echo "$num" | grep -o '[^[:digit:],[:space:]]' | sed ':t;N;s/\n//g; b t;'`
[ -n "$num_second" ] && echo "your inout is error, please inpuit again" && exit 18
echo "your input num is $num"
}
test_num
[dayuanshuai@idys day01_sh] bash exit_num.sh
please input numsdfs2342
your inout is error, please inpuit again
[dayuanshuai@idys day01_sh] echo $?
18
[dayuanshuai@idys day01_sh] bash exit_num.sh
please input num123
your input num is 123
[dayuanshuai@idys day01_sh] echo $?
0
break
语句break
语句时,会结束整个当前循环。 而 continue
语句也是结束循环的语句,不过 continue
语句单次当前循环,而下次循环会继续。break
语句演示[dayuanshuai@idys day01_sh] cat break_type.sh
# !/bin/bash
function break_num(){
for i in `seq 1 100`;do
if [ $i -eq 4 ];then
echo "your num is into 4,we will auto exit"
break
fi
echo "$i"
done
}
break_num
[dayuanshuai@idys day01_sh] bash break_type.sh
1
2
3
your num is into 4,we will auto exit
continue
语句continue
语句,continue
也是结束流程控制的语句。如果在循环中,continue
语句只会结束单次当前循环continue
语句演示[dayuanshuai@idys day01_sh] cat continue_type.sh
# !/bin/bash
function contine_perform(){
for((i=0;i<10;i++));do
if [ $i -eq 6 ];then
echo "**************"
continue
fi
echo "$i"
done
}
contine_perform
continue
语句演示[dayuanshuai@idys day01_sh] bash continue_type.sh
0
1
2
3
4
5
**************
7
8
9
continue
只会退出单次循环,所以并不影响后续的循环