目录
1.文本处理工具,文件查找工具,文本处理三剑客, 文本格式化命令(printf)的相关命令及选项
2. 总结文本处理的grep命令相关的基本正则和扩展正则表达式。
3. 总结变量命名规则,不同类型变量(环境变量,位置变量,只读变量,局部变量,状态变量)如何使用。
4. 通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?
5. 结合编程的for循环,条件测试,条件组合,完成批量创建100个用户
1.文本处理工具,文件查找工具,文本处理三剑客, 文本格式化命令(printf)的相关命令及选项
1.1文本常见处理文具
cat查看文本内容
格式:
cat [OPTION]… [FILE]…
常见选项:
-E:显示行结束符$
-A:显示所有控制符
-n:对显示出的每一行进行编号
-b:非空行编号
-s:压缩连续的空行成一行
cat test.txt
[root@rocky8 ~]$ cat test.txt
cat 命令实例[root@rocky8 ~]$ cat -n test.txt
1 cat 命令实例1
2 cat 命令实例2
3 cat 命令实例3
tac:逆向显示文本内容
[root@rocky8 ~]$ tac test.txt
cat 命令实例3
cat 命令实例2
cat 命令实例1
rev:将同一行内容逆向显示
[root@rocky8 ~]$ rev test.txt
1例实令命 tac
2例实令命 tac
3例实令命 tac
hexdump:查看非文本文件内容
[root@rocky8 ~]$ hexdump anaconda-ks.cfg
0000000 7623 7265 6973 6e6f 523d 4548 384c 230a
0000010 5520 6573 6720 6172 6870 6369 6c61 6920
0000020 736e 6174 6c6c 670a 6172 6870 6369 6c61
less:实现分页显示内容
tree -d /etc | less
/etc
├── accountsservice
│ └── user-templates
├── alsa
│ └── conf.d
├── alternatives
├── anaconda
│ ├── conf.d
│ └── product.d
├── audit
│ ├── plugins.d
│ └── rules.d
├── authselect
│ └── custom
├── auto.master.d
├── avahi
head:显示文本或标准输入的的前面行
格式:
head [OPTION]... [FILE]..
选项:
-c # 指定前#字节
-n # 指定前#行,#如果为负数,表示为从文件头取到倒数第#行前
-# 同上
[root@rocky8 ~]$ head -n3 /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
tail:显示文本或标准输入的倒数行
格式:
tail [OPTION]... [FILE]..
选项:
-c # 指定后#字节
-n # 指定后#行,#如果为负数,表示为从第#行开始到文件结束
-# 同上
-f 跟踪显示文件新追加的内容,常用日志监控,相当于 --follow=descriptor,当文件删除后再新建同名文件,无法继续跟踪文件
-F 跟踪文件名,相当于--follow=name --retry,当文件删除后再新建同名文件,将可以继续追踪文件
[root@rocky8 ~]$ cat test.txt
命令实例1
命令实例2
命令实例3
命令实例4
命令实例5
[root@rocky8 ~]$ tail -n3 test.txt
命令实例3
命令实例4
命令实例5
cut:按列抽取文本
格式:
cut [OPTION]… [FILE]…
选项:
-d:DELITITER:指明分隔符,默认tab
-f:FILEDS:
#:第#个字符,例如:3
#,#[,#]:离散的多个字段,例如1,3,6
#-#:连续的多个字段,例如1-6
混合使用:1-3,7
-c 按字符切割
[root@rocky8 ~]$ ifconfig |head -n2|tail -n1|cut -d' ' -f10
10.0.0.150
paste 合并多个文件
格式:
paste [OPTION]… [FILE]…
选项:
-d #分隔符:指定分隔符,默认用TAB
-s #所有行合成一行显示
[root@rocky8 ~]$ cat test.txt
命令实例1
命令实例2
命令实例3
命令实例4
命令实例5
[root@rocky8 ~]$ cat test1.txt
合并1
合并2
合并3
[root@rocky8 ~]$ paste test.txt test1.txt
命令实例1 合并1
命令实例2 合并2
命令实例3 合并3
命令实例4
命令实例5
[root@rocky8 ~]$ paste -d":" test.txt test1.txt
命令实例1:合并1
命令实例2:合并2
命令实例3:合并3
命令实例4:
命令实例5:
wc:收集文本统计数据
选项:
-l 只计数行数
-w 只计数单词总数
-c 只计数字节总数
-m 只计数字符总数
-L 显示文本中最长行的长度
[root@rocky8 ~]$ cat test.txt
命令实例1
命令实例2
命令实例3
命令实例4
命令实例5
[root@rocky8 ~]$ wc -l test.txt
5 test.txt
sort:文本排序
格式:
sort [options] file(s)
选项:
-r 执行反方向(由上至下)整理
-R 随机排序
-n 执行按数字大小整理
-h 人类可读排序,如: 2K 1G
-f 选项忽略(fold)字符串中的字符大小写
-u 选项(独特,unique),合并重复项,即去重
-t c 选项使用c做为字段界定符
-k # 选项按照使用c字符分隔的 # 列来整理能够使用多次
[root@rocky8 ~]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 883796 0 883796 0% /dev
tmpfs 914116 0 914116 0% /dev/shm
tmpfs 914116 9516 904600 2% /run
tmpfs 914116 0 914116 0% /sys/fs/cgroup
/dev/mapper/rl-root 73364480 5766420 67598060 8% /
/dev/mapper/rl-home 133071376 960928 132110448 1% /home
/dev/sdb5 2086912 1096180 990732 53% /mysql
/dev/sdb1 1998672 6148 1871284 1% /logs
/dev/sda1 1038336 260176 778160 26% /boot
tmpfs 182820 12 182808 1% /run/user/42
tmpfs 182820 0 182820 0% /run/user/0
[root@rocky8 ~]$ df | tr -s ' ' % |cut -d'%' -f5|sort -nr|head -n1
53
uniq:删除前后相接的重复的行
格式:
unqi [OPTION]...[FILE]...
选项:
-c:显示每行重复出现的次数
-d:仅显示重复过的行
-u:仅显示不曾重复的行
[root@rocky8 ~]$ cut -d' ' -f1 access_log|sort|uniq -c|sort -nr|head -n3
4870 172.20.116.228
3429 172.20.116.208
2834 172.20.0.222
1.2 文件查找工具
非实时查找(数据库查找):locate
实时查找:find
locate
格式:
locate [OPTION]… [PATTERN]…
常用选项:
-i 不区分大小写的搜索
-n N 只列举前N个匹配项目
-r 使用基本正则表达式
[root@rocky8 ~]$ locate -r '\.conf$'
/apps/nginx/conf/fastcgi.conf
/apps/nginx/conf/nginx.conf
/boot/loader/entries/dbc5253c952a4654b60161e38fa43d8b-0-rescue.conf
/boot/loader/entries/dbc5253c952a4654b60161e38fa43d8b-4.18.0-372.9.1.el8.x86_64.conf
/etc/asound.conf
/etc/autofs.conf....
....
find
格式:
find [OPTION]… [查找路径] [查找条件] [处理动作]
工作特点:
查找速度略慢
精确查找
实时查找
查找条件丰富
可能只搜索用户具备读取和执行权限的目录
根据属主、属组查找
-user USERNAME #查找属主为指定用户的文件
-group GRPNAME #查找属组为指定组的文件
-uid UserID #查找属主为指定UID号的文件
-gid GroupID #查找属组为指定GID号的文件
-nouser #查找没有属主的文件
-nogroup #查找没有属组的文件
1.3 文本处理三剑客
文本处理三剑客之 grep
文本搜索工具,对于文本的行基于模式(正则表达式)进行过滤
格式:
grep [OPTIONS] PATTERN [FILE…]
选项:
-color=auto 对匹配到的文本着色显示
-m # 匹配#次后停止
-v 显示不被pattern匹配到的行,即取反
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息
-A # after, 后#行
-B # before, 前#行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系,如:grep –e ‘cat ’ -e ‘dog’ file
-w 匹配整个单词
-E 使用ERE,相当于egrep
-F 不支持正则表达式,相当于fgrep
-P 支持Perl格式的正则表达式
-f file 根据模式文件处理
-r 递归目录,但不处理软链接
-R 递归目录,但处理软链接
查看硬盘分区利用最大率的值
[root@rocky8 ~]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 883796 0 883796 0% /dev
tmpfs 914116 0 914116 0% /dev/shm
tmpfs 914116 9516 904600 2% /run
tmpfs 914116 0 914116 0% /sys/fs/cgroup
/dev/mapper/rl-root 73364480 5775288 67589192 8% /
/dev/mapper/rl-home 133071376 960928 132110448 1% /home
/dev/sdb5 2086912 1096180 990732 53% /mysql
/dev/sdb1 1998672 6148 1871284 1% /logs
/dev/sda1 1038336 260176 778160 26% /boot
tmpfs 182820 12 182808 1% /run/user/42
tmpfs 182820 0 182820 0% /run/user/0
[root@rocky8 ~]$ df|grep "^/dev/sd"|tr -s ' ' %|cut -d'%' -f5|sort -nr|head -n1
53
文本处理三剑客之 sed
sed是从文本或管道中先读取一行,处理一行,输出一行;再读取一行,处理一行,直到最后一行,每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间 ,这种设计使得sed性能很高,打开速度和执行速度非常快。
sed基本用法
格式:
sed [option]… ‘script;script;…’ [inputfile…]
选项:
-n 不输出模式空间内容到屏幕,即不自动打印
-e 多点编辑
-f FILE 从指定文件中读取编辑脚本
-r, -E 使用扩展正则表达式
-i.bak 备份文件并原处编辑
-s 将多个文件视为独立文件,而不是单个连续的长文件流#说明:
-ir 不支持
-i -r 支持
-ri 支持
-ni 危险选项,会清空文件
script格式:
‘地址命令’
地址格式:
1.不给地址,对全文进行处理
2.单地址:
#:指定的行,$:最后一行
/pattern/ :被此处模式所能匹配到的一行
3.地址范围:
#,# 从#行到第#行,3,6 从第3行到第6行
#,+# 从#行到+#行,3,+4 从第3行到第7行
4.步进:~
1~2 奇数行
2~2 偶数行
常用命令:
p 打印当前模式空间内容,追加到默认输入之后
Ip 忽略大小写输出
! 模式空间中匹配行取反处理
查找替代:
s/pattern/string/修饰符 查找替代,支持使用其他分隔符:s###,s@@@
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w /PATH/FILE 将替换成功的行保存至文件中
I,i 忽略大小写
取ip地址
[root@rocky8 ~]$ ifconfig ens160 | sed -rn '2s#^.*net ([0-9.]+).*#\1#p'
10.0.0.150
文本处理三剑客之 awk
awk:报告生成器,格式化文本输出
格式:
awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
选项:
-F “分隔符” 指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符
-v var=value 变量赋值
printf 可以实现格式化输出
格式:
printf “FORMAT”, item1, item2, …
取出分区利用率
[root@rocky8 ~]$ df | awk '{print $1,$5}'
Filesystem Use%
devtmpfs 0%
tmpfs 0%
tmpfs 2%
tmpfs 0%
/dev/mapper/rl-root 8%
/dev/mapper/rl-home 1%
/dev/sdb5 53%
/dev/sdb1 1%
/dev/sda1 26%
tmpfs 1%
tmpfs 0%
2. 总结文本处理的grep命令相关的基本正则和扩展正则表达式。
2.1基本正则表达式
字符匹配:
. 匹配任意单个字符(除了\n),可以是一个汉字或其它国家的文字
[] 匹配指定范围内的任意单个字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
[^] 匹配指定范围外的任意单个字符,示例:[^wang]
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比 [:blank:]包含的范围广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃…)
[:digit:] 十进制数字
[:xdigit:] 十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
**[:punct:] 标点符号
\s #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\r\t\v]。注意 Unicode
正则表达式会匹配全角空格符
\S #匹配任何非空白字符。等价于 [^\f\r\t\v]
\w #匹配一个字母,数字,下划线,汉字,其它国家文字的字符,等价于[[:alnum:]字]
\W #匹配一个非字母,数字,下划线,汉字,其它国家文字的字符,等价于[^[:alnum:]字
[root@rocky8 ~]$ ls /etc|grep 'rc[.0-6]'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
匹配次数:
用在要指定次数的字符后面,用于指定前面的字符要出现的次数
* #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* #任意长度的任意字符
? #匹配其前面的字符出现0次或1次,即:可有可无
+ #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
{n} #匹配前面的字符n次
{m,n} #匹配前面的字符至少m次,至多n次
{,n} #匹配前面的字符至多n次,<=n
{n,} #匹配前面的字符至少n次
[root@rocky8 ~]$ cat test.txt
123
1223
1222222222222223
122233333333
[root@rocky8 ~]$ grep '123' test.txt
123
[root@rocky8 ~]$ grep '12*3' test.txt
123
1223
1222222222222223
122233333333
位置锚定
可以用于定位出现的位置^ #行首锚定, 用于模式的最左侧
$ #行尾锚定,用于模式的最右侧
^PATTERN$ #用于模式匹配整行
^$ #空行
< 或 \b #词首锚定,用于单词模式的左侧
> 或 \b #词尾锚定,用于单词模式的右侧
<PATTERN> #匹配整个单词
#注意: 单词是由字母,数字,下划线组成
[root@rocky8 ~]$ cat test.txt
123
122334
23344
[root@rocky8 ~]$ grep '^2' test.txt
23344
[root@rocky8 ~]$ grep '4$' test.txt
122334
23344
2.2扩展正则表达式
字符匹配:
. 任意单个字符
[wang] 指定范围的字符
[^wang] 不在指定范围的字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃…)
[:digit:] 十进制数字
[:xdigit:] 十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
次数匹配:
* 匹配前面字符人一次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
位置锚定:
^ 行首
$ 行尾
\<,\b 语首
\>,\b 语尾
分组其他:
() 分组 ;后向引用:\1,\2 ;\0 表示正则表达式匹配的所有字符
| 或者
扩展表达式取ip地址
[root@rocky8 ~]$ ifconfig ens160|grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -n1
10.0.0.150
3. 总结变量命名规则,不同类型变量(环境变量,位置变量,只读变量,局部变量,状态变量)如何使用。
3.1变量命名要求
区分大小写
不能使程序中的保留字和内置变量:如:if, for
只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
变量赋值:
name=‘value‘
value可以是以下多种形式
直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND`
变量赋值是临时生效,退出终端后会自动删除。
变量引用:
$name
${name}
弱引用和强引用
“$name" 弱引用,其中的变量引用会被替换成变量值
’$name‘ 强引用,其中的变量引用不会被替换成变量值,而保持原字符串
[root@rocky8 ~]$ homework=‘第二周’
[root@rocky8 ~]$ echo $homework
‘第二周’
[root@rocky8 ~]$ echo homework is $homework
homework is ‘第二周’[root@rocky8 ~]$ echo "homework is $homework"
homework is ‘第二周’
[root@rocky8 ~]$ echo 'homework is $homework'
homework is $homework
set 显示已定义的所有变量
unset <name> 删除变量
3.2环境变量
可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量
一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程
一般只在系统配置文件中使用,在脚本中较少使用
声明并赋值
export name=VALUE
declare -x name=VALUE#或者分两步实现
name=VALUE
export name
显示所有环境变量:
e n v
p r i n t e n v
e x p o r t
d e c l a r e − x
查看指定进程的环境变量
cat /proc/$PID/environ
删除变量:
unset name
3.3只读变量
只能声明定义,但后续不能修改和删除,即常量
声明只读变量:
readonly name
declare -r name
查看只读变量:
readonly [-p]
declare -r
3.4位置变量
在bash shell中内置的变量, 在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, … 对应第1个、第2个等参数,shift [n]换位置
$0 命令本身,包括路径
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数注意…@ $* 只在被双引号包起来的时候才会有差异
清空所有位置变量
set --
3.5退出状态码变量
进程进行后,将用$?保存状态码的相关数字,不同的值反应成功或失败,$?取值范例0-255
$?的值为0 #代表成功
$?的值为1-255 #代表失败
4. 通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?
[root@rocky8 ~]$ cat rabbit_chook.sh
#!/bin/bash
HEAD=$1
FOOT=$2RABBIT=$(((FOOT-HEAD-HEAD)/2))
CHOOK=$[HEAD-RABBIT]
echo RABBIT:$RABBIT
echo CHOOK:$CHOOK
[root@rocky8 ~]$ bash rabbit_chook.sh 30 80
RABBIT:10
CHOOK:20
5. 结合编程的for循环,条件测试,条件组合,完成批量创建100个用户
[root@rocky8 ~]$ cat create_user.sh
#!/bin/bashfor i in {1..100}
do
username="user$i"
if id -u $username >/dev/null 2>&1; then
echo "$username is already exists!"
else
useradd $username
echo "User $username has been added!"
fi
done
[root@rocky8 ~]$ bash create_user.sh
User user1 has been added!
User user2 has been added!
User user3 has been added!
......
User user97 has been added!
User user98 has been added!
User user99 has been added!
User user100 has been added![root@rocky8 ~]$ useradd user99
useradd: user 'user99' already exists