第2周作业

1. 总结学过的权限,属性及ACL相关命令及选项,示例。

权限和属性

1、三种角色:u-g-o
属主(owner)-属组(group)-其他用户(other)
2、三种权限:r-w-x 4-2-1
读权限(read) - 写权限(write)- 执行权限(execute)
3、范例:

修改属主属组
	chown tom. my.log		# 只修改属主
	chown .tom my.log		# 只修改属组 
	chown -R mysql.mysql /data/mysql   # 递归更改多级目录的属主和属组
文件权限	
	#角色: u g o a    赋值:+ - =     权限: r w x   4 2 1
	#常用写法:
	u+r		#属主加读权限
	g-x		#属组去掉执行权限
	a=rwx	#所有用户都有读写执行权限
	
	#八进制表示
	---	0;--x  1;-w- 2; r-- 4 -wx 3; r-x 5; rw- 6;rwx 7
	rwxr-xr-x 	755
	rw-r--r-  	644
	rw-r----	640
	chmod 755	test.sh
	chmod a+x	test.sh

4、特殊权限
SUID-------- s ------- 4(二进制文件) 占属主的执行权限位
SGID-------- s ------- 2 (文件夹) 占属组的执行权限位
STICKY------ t ------- 1 (目录) 占other 的执行权限位
进程访问文件时的权限,取决于进程的发起者
查看特殊权限: ll -d /data/a1.txt

5、设定文件特殊属性:
a #对文件:可追加内容,不可修改和删除。对目录,可新建修改不可删除
A #不更新atime,节点IO
i # 对文件,不可被删除不可被修改,对目录,可修改查看目录中的文件,不可新建文件,不可删除文件
s #彻底删除文件,用0填充原来的数据块
u #防止误删除,这是指原来存储该文件的块不会被新的数据覆盖
c #文件会被压缩

	chatter +i test.log	#防止误删除
	lsatter a.txt	#显示文件特殊属性
ACL

生效顺序:
所有者——>自定义用户——>所属组——>自定义组——>其他人

常用选项:

-m|--modify=acl			#修改acl权限
-M|--modify-file=file	#从文件读取规则
-x|--remove-acl			#删除文件acl权限
-X|--remove-file=file	#从文件读取规则
-b|--remove-all			#删除文件所有acl权限
-k|--remove-default		#删除默认acl权限
--set=acl				#用新规则替换旧规则
--set-file=file			#从文件读取规则
--mask					#重新计算mask的值
-n|--no-mask			#不重新计算mask的值
-d|--default			#在目录上设置默认acl 
-R|--recursive			#递归执行
-L|--logical			#与-R一起执行,acl应用到软链接指向的文件上
-P|--physical			#与-R一起执行,acl不应用到软链接指向的文件上

范例:

#修改
setfacl -m u:mage:- a.txt

#查看
[root@rocky154 ~]# getfacl a.txt 
#file: a.txt
#owner: root
#group: root
user::rw-
user:mage:---
group::r--
mask::r--
other::r--

#移除
setfacl -b file1	#移除所有

2.结合vim几种模式,学会使用vim几个常见操作。

1)打开文件,并在打开文件(命令模式)之后退出
vim /etc/issue		#打开
:q					#退出
:q!					#不存盘退出
:x					#写入并退出
:wq					#写入并退出

2)打开文件(命令模式)之后,进入插入模式。并在插入模式中如何回到打开文件的状态(命令模式),并在命令模式之后如何退出文件。
vim a.txt  打开文件,按键盘 i 进入插入模式。 按ESC键退出插入模式,按:wq 存盘退出。


3)用VIM 打开文件,编辑一段文字保存退出
在这里插入图片描述
4)用cat查看验证文件内容。
在这里插入图片描述

3.总结学过的文本处理工具,文件查找工具,文本处理三剑客, 文本格式化命令(printf)的相关命令及选项,示例。

1) 文本处理工具
  • 查看文本内容
    • cat
-E	#显示行结束符$
-A	#显示所有控制符
-n	#对显示出的每一行进行编号
-b	#非空行编号
-s	#压缩连接的空行成一行

在这里插入图片描述

- nl	#显示行号

在这里插入图片描述

- tac		#逆序显示内容, 行倒序显示

在这里插入图片描述

- rev		#将同一行的内容逆向显示,同一行倒序

在这里插入图片描述

  • 分页查看文件内容
    • more
    常用选项:
    		-d		#在底部显示提示
    		-s		#压缩连续空行	 
    命令选项:
    		空格键		#翻页
    		回车键		#下一行
    		h		#显示帮助
    		:f 	#显示文件名和当前行号
    		=	#显示行号
    

在这里插入图片描述在这里插入图片描述


	less
	常用选项:
			-e		#显示完成后自动退出
			-N		#显示行号
			-s		#压缩连续空行
			-S		#不换行显示较长的内容
	命令选项
			h		#显示帮助
			/string	#搜索
			!cmd	#执行命令
		
- 显示文本前面或后面的行内容
	
	- head
常用选项
-c			#指定获取前N字节
-n | -N		#指定获取前N行,N如果是负数,表示从文件头取到倒数第N行前
-q			#不输出文件名
-v			#输出文件名
-z			#以NULL字符而不是换行符作为行尾分隔符

在这里插入图片描述

  • tail #查看文件或标准输入的倒数行
常用选项:
	-c			#指定获取后N字节
	-n | -N		#指定获取后N行,N如果是负数,表示从第N行开始到文件结束
	-q			#不输出文件名
	-f			#跟踪显示文件fd新追加的内容,常用日志监控,当删除再新建同名文件,无法继续追踪
	-F 			#跟踪文件名,当删除文件再新建同名文件,可继续追踪
	-z			#以NULL字符而不是换行符作为行尾分隔符

在这里插入图片描述

  • cut #提取文本或STDIN数据的指定列
	常用选项
		   -b	#以字节分割,指定要显示的列
		   -c	#以字符分割
		   -d	#指定分割符,默认Tab
		   -f 	#要显示的列,-f1, -f1,2,3, -f 1-3,4
		   -s	#不显示没有包括分割符的内容
		   --output-delimiter  #用指定字符代替分隔符
		   -z	#以NULL字符而不是换行符作为行尾分隔符

在这里插入图片描述

  • paste #合并多个文件
    合并多个文件同行号的行到一行
	常用选项:
		-d	#指定分割符,默认用TAB
		-s	#合成一行显示
		-z 	#以NULL字符而不是换行符作为行尾分隔符
  • 分析文本的工具
    • wc: 收集文本统计工具
格式:
wc [option]... [file]
常用选项:
-l		#只统计行数
-w		#只统计单词总数
-c		#只统计字节总数
-m		#只统计字符总数,比如中文1个字是1字符,占2个字节
-L		#显示文件中最长行的长度
范例:
wc a1.txt	#不带选项,默认统计的是 行,单词总数,总字节数
[root@ubuntu150 ~]# wc a1.txt 
  3  28 115 a1.txt
#重定向写法
[root@ubuntu150 ~]# cat /var/log/syslog | wc -l
7469
#不显示第一行,用tail -n ;实际行数-1即可
df | tail -n $(echo `df | wc -l`-1|bc)
    • sort:文本排序
sort [option] ... [file]
常用选项
-b		#忽略文件中的空白
-f		#忽略大小写
-h		#人类可读排序
-M		#以月份排序
-n		#以数字大小排序
-R		#随机排序
-r		#倒序
-t		#指定列分割符
-k		#指定排序列
-u		#去重
-z		#以 NUL字符而非换行符为行尾分隔符
范例:
#统计日志访问量
[root@ubuntu150 ~]# cut -d" " -f1 /var/log/nginx/access.log |sort -u |wc -l
2


    • uniq:去重
uniq [option] [input[output]]
常用选项
-c		#显示每行出现次数
-d		#仅显示有重复行
-D		#显示所有重复行具体内容
-u		#仅显示不重复的行
-z		#以 NUL 字符而非换行符作为行尾分隔符
范例:
#统计日志访问量最多的前三名的请求
[root@ubuntu150 nginx]# 
cd /var/log/nginx/
cat access.log |cut -d " " -f1 | uniq -c|sort -nr
      9 10.0.0.1
      5 10.0.0.157
      1 10.0.0.150

    • diff:比较两个文件之间的区别
diff [option] ... files
常用选项 
-u		#选项来输出"统一的(unified)"diff 格式文件,
		#最适用于补丁文件
范例:
#将对比结果保存至文件
[root@ubuntu150 ~]# diff -u a1.txt a2.txt > a.patch
rm -f a2.txt				#删除a2.txt
patch -b a1.txt a.patch		#和a1.txt与a.patch 还原
#还原出来的是a2
#原来a1.txt 增加了后缀 .orig
a1.txt.orig
    • patch:复制在其他文件中进行的改变(谨慎使用)
常用选项:
-b		#备份
#用 a1.txt和 a.path 生成一个名为a1.txt的文件,但内容是原来a2.txt文件中的内容
#-b 选项则备份了现有的 a1.txt 为"a1.txt.orig"
patch -b a1.txt a.patch

- vimdiff:相当于 vim -d
	vimdiff a1.txt a2.txt	#同时打开2个文件,标出不同之处
	
- cmp:查看二进制文件的不同
	cmp /bin/dir /bin/ls
2)文件查找工具
  • locate
    • locate 查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db
    • 索引的构建是在系统较为空闲时自动进行(周期任务),执行updatedb可以更新数据库
    • 模糊查看、非实时查找、搜索的是文件全路径,不仅仅是文件名
    • 可能只搜索用户具备读和执行权限的目录
常用选项
-A	#输出所有能匹配到的文件名,不管文件是否存在
-b	#仅匹配文件名部分,而不匹配路径中的内容
-c	#只输出找到的数量
-d	#指定数据库
-e	#仅打印当前现有文件的条目
-L	#遇到软链接时则跟随软链接去其对应的目标文件中查找(默认)
-i	#忽略大小写
-l	#只显示前N条匹配数据
-P	#不跟随软链接
-r	#使用基本正则表达式
--regex	#使用扩展正则表达式
-s	#忽略向后兼容
-w	#全路径匹配,就是只要在路径里面出现关键字(默认)

#命令范例
apt install mlocate	| dnf -y install mlocate	#安装
locate -n 3 conf 
updatedb
locate -b share		#仅搜索文件名中包含 share 的内容
locate -c conf		#显示数量
locate -n 10 conf	#显示前10条
locate -r '\.conf$'
locate -d /tmp/nofile conf
  • find
      1. 实时查找工具,通过遍历指定路径完成文件查找;
      1. 特点: 查找速度略慢; 精确查找;实时查找;查找条件丰富
      1. 范例:
find /etc/ -maxdepth 2			#指定最大搜索目录深度,目录下的文件为第1级
find /etc/ -mindepth 2			#指定最小搜索目录深度
find /etc/ -maxdepth 2 -mindepth 2
find /etc/ -depth				#先处理文件再处理目录,默认是先目录再文件
find -name fa*				#指定文件名查找,区分大小写
find -iname Fa*.log			#指定文件名查找,不区分大小写
find -regex ".*\.log$"		#正则表达式,文件
find -regex ".*dir3$"		#路径匹配
find -user www-dat			#指定属主
find -group adm				#指定属组
find -1000 -1000			#指定属主属组的ID
find -type d				#根据文件类型查找(d|f|l|s|b|c|p)
f——普通文件
l——符号链接文件
s——套接字文件
b——块设备文件
c——字符设备文件
p——管道文件
find dir1/dir2/dir3/ -empty					#查找空文件或空目录
find -name "*log" -a -type f				#-a 与,-o 或,-not|! 非 (组合查找)
find -path './dir1' -prune -o -name "*.txt" #排除dir1目录中的 txt文件
find /etc/ -path /etc/security -prune -o -name "*.conf"	#排除security目录中的 conf文件
find \( -path './dir1' -o -path './dir4' \) -prune -o -name "*.txt" -print										#排除多个目录需要用括号包起来,再接 -prune
find /var/log/ -size 3k -ls					#查找文件大小 2k<?<=3k 的文件
find /var/log/ -size -3k -ls 				#查找文件大小 ? <=2k
find /var/log/ -size +3k -ls				#表示 ? > 3k
find -amin +5								#查找5分钟前被访问的文件
find -perm 444 -ls							#精确匹配,ugo都只能是 r权限
find -perm /444 -ls							#或关系
find -perm -444 -ls							#ugo至少都要有权限

#处理动作
-print			#默认的处理动作,显示至屏幕
-print0			#不换行输出,常用于配合 xargs
-ls				#类似于对查找到的文件执行 ls -ils 命令格式输出
-fls file		#查找到的所有文件的长格式信息保存至指定文件中,相当于 -ls > file
-delete			#删除查找到的文件,慎用!
-ok	COMMAND {} \; 		#对查找到的每个文件执行由 COMMAND 指定的命令,对于每个文件执行命令之前,都会交互式要求用户确认
-exec COMMAND {} \;		#对查找到的每个文件执行由COMMAND指定的命令
{}				#用于引用查找到的文件名称自身。
#备份以log结尾的文件
find -name "*log" -exec cp {} {}.back \;


3)文本处理三剑客
  • grep

范例

#标准输入: 			grep hello
#处理文件: 			grep root /etc/passwd
#管道:	  			cat /etc/passwd | grep root
#标准输入重定向:		grep too < /etc/passwd
#取前三行:	  		grep -m 3 bin /etc/passwd
#取反,取不匹配的行:	grep -v "#" /etc/fstab	(不看注释行)
#不区分大小写:		grep -i ROoT /etc/passwd
#显示行号:			grep -n bash /etc/passwd
#显示匹配的行数:		grep -c bash /etc/passwd
#仅显示匹配到的内容:	grep -o bash /etc/passwd
#静默模式:			grep -q root /etc/passwd    (echo $? 输出 0)
#显示匹配root的行		grep -e root -e bash /etc/passwd
#或匹配bash的行		
#显示匹配rootr的行且	grep root /etc/passswd | grep bash
#匹配bash的行
#从文件读取匹配规则	grep -f test.txt /etc/passwd
#递归匹配			grep -r root /etc/*		(不处理链接)
#递归匹配			grep -R root /etc/*		(处理链接)
#命令行展开			grep `whoami` /etc/passwd
#变量展开			grep "$USER" /etc/passwd
#取CPU核数:			grep -c processor /proc/cpuinfo
#正则写法:			grep "^\(.*\)\>.*\<\1$" /etc/passwd
#扩展正则写法1:	   grep -E "^(.*)\>.*\<\1$" /etc/passwd
#扩展正则写法2:		egrep "^(.*)\>.*\<\1$" /etc/passwd
#过滤掉空行和注释:	grep -Ev "^$|#" /etc/fstab

  • sed

sed 基本用法
格式: set [option]… [script-only-if-no-other-script} [input-file]…

常用选项
-n			#不输出模式空间内容到屏幕,即不自动打印
-e	script	#多个script,or 的关系
-f	script	#从指定文件中读取编辑脚本
-i			#直接修改文件,-i.bak 以.bak后缀备份原文件
-c			#配合-i 一起使用,保留原文件
-l N		#指定每行长度,如果过长,就拆分成多行,要加'l'
--posix		#禁用 GNU扩展
-E|-r		#扩展正则表达式
-s			#将多个文件视为独立文件,而不是单个连续的长文件流
-ri			#带扩展正则修改文件	*注意不支持 -ir的写法
-i -r 		#修改文件,扩展正则表达式匹配
-ni			#此组合危险,会清空文件。

# script 格式: ”**Addr**Cmd"    地址命令 在哪些行 执行什么操作
#地址格式:
  #为空,表示对全文进行处理
  #单地址指定行
	N			#具体行号
	$			#最后一行
	/pattern/	#能被匹配到的每一行
  #范围地址:
  	M,N					#第M行到第N行
  	M,+N					#第M行到 第M+N行。 3,+4 表示从第3行到第(3+4)7行
  	/pattern1/,/pattern2/	#从第一个匹配行开始,到第二个匹配行中间的行
  	M,/pattern/			#行号开始,匹配结束
  	/pattern/,N			#匹配开始,行号结束
  #步长
  	1~2						#奇数行
  	2~2						#偶数行
#命令:
	p		#打印当前模式空间内容,追加到默认输出之后
	Ip		#忽略大小写
	d		#删除模式空间匹配的行,并立即启用下一轮循环
	a		#在指定行后面追加文本,支持使用\n实现多行追加
	i		#在行前面插入文本
	c		#替换行为单行或多行文本
	w file	#保存模式匹配的行至指定文件
	r file	#读取指定文件的文本至模式空间中匹配到的行后
	=		#为模式空间中的行打印行号
	!		#模式空间中匹配行取反处理
	q		#结束或退出sed
#查找替代
	s/pattern/replace/修饰符		#查找替换,支持使用其它分隔符,可以是其它形式: s@@@,s###
	#修饰符
	g			#行内全局替换
	p			#显示替换成功的行
	w file		#将替换成功的行保存至文件中
	I|i			#忽略大小写
	
	#向后引用
	\1			#第一个分组
	\2			#第二个分组
	\N			#第N个分组
	&			#所有搜索内容
范例:
sed [option] {script}
#输出第一行
sed -n '1p' /etc/passwd
#输出最后一行
sed -n '$p' /etc/passwd
#正则匹配,输出包含root 的行
sed -n '/root/p' /etc/passwd
#正则匹配,输出以root 开头的行
sed -n '/^root/p' /etc/passwd
#正则匹配,输出以 bash 结尾的行
sed -n '/bash$/p' /etc/passwd
#正则匹配,显示注释行行号
sed -n '/^#/=' /etc/fstab
#行号开始,正则结束
sed -n '8,/mail/p' /etc/passwd
################################################################
添加内容范例:
#匹配行后插入:
sed '/bbb/a\----' test.txt		(命令a 在指定行后追加)
#匹配行前插入:
sed '2i\====' test.txt			(命令i 在指定行前插入)
#替换,第一行替换成-----
sed "1c\-----" test.txt			(命令c 替换行为单行或多行)
sed "1c\----\n====" test.txt
sed "1,4c\=====" test.txt 		(多行替换成1行)
**\的作用,\后会保留空格**

#取IP行
ifconfig eth0 |sed -n '/netmask/p'
ifconfig eth0 |sed -n '2p'

#变量展开;命令展开,都用双引号“”
sed -n "/$USER/p" /etc/passwd
sed -n "/$(whoami)/p" /etc/passwd
sed -n "/$[$(id -u)+1]p" /etc/passwd

#只显示非#开头的行
sed -n '/^#/!p' /etc/fstab

#修改文件,先把num.txt备份成了num.txt.bak,然后删除了2到7行
sed -i.bak '2,7d' num.txt		(d,删除模式空间2到7行)

#将#开头的行删除#号
sed -ri.bak '/^#/s/^#//' fstab
sed -E -i.bak 's/^#(.*)/\1/' fstab

#搜索替换和&(引用)
sed -n 's/root/ROOT/gp' /etc/passwd			(g行内全局替换)
sed -n 's/root/&er/gp' /etc/passwd		(root替换成rooter,&引用所有搜索内容
sed -n 's/r..t/&er/gp' /etc/passwd		(. 匹配任意单个字符除了\n。).. 就是匹配任意2个字符 root,rabt,rttt。

#除指定文件外其余删除
rm -f `ls | grep -Ev 'f(1|3|5|7|9)\.log'`	(后边ls语句需要用``展开命令行)
rm -f `ls | sed -n '/f[^13579]\.log/p'`
ls | grep -Ev 'f(1|3|5|7)\.log' | sed -n 's/.*/rm &/p' | bash

#取基名和目录名:
echo "/etc/nginx/conf.d/" | sed -En 's#(^/.*/)([^/]+)/?#\1#p'	#把分隔符由/ 换成了#)s/ s# s@

#取文件的前缀和后缀
echo a.tar.gz.txt | sed -En 's/(.*)\.([^.]+)$/\1 \2/p'

#修改网卡名称
 sed -Ei '/^GRUB_CMDLINE_LINUX/s#"$# net.ifnames=0"#p' /etc/default/grub

#修改selinux 配置
sed -Ei.bak 's/^SELINUX=.*/SELINUX=disabled/' config

  • 解释: 查找 GRUB_CMDLINE_LINUX/开头的行,然后把行尾的引号 ”(“$ )替换成 net.ifnames=0” 。net前有空格。
    在这里插入图片描述

  • sed 高级用法

常见的高级命令
p		#打印模式空间开端至\n内容,并追加到默认输出之前
h		#把模式空间中的内容覆盖至保持空间中
H		#把模式空间中的内容追加至保持空间中
g		#从保持空间取出数据覆盖至模式空间
G		#从保持空间取出数据追加至模式空间
x		#把模式空间中的内容与保持空间中的内容进行互换
n		#读取匹配到的行的下一行覆盖至模式空间
N		#读取匹配到的行的下一行追加至模式空间
d		#删除模式空间中的行
D		#如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d 命令那样启动正常的新循环

范例:
sed -n 'n;p' FILE
seq 10 | sed 'N;s/\n//'
sed '1!G;h;$!d' FILE
seq 10 | sed -n '/3/{g;1!p;};h' #前一行
seq 10 | sed -nr '/3/{n;p}' #后一行
sed 'N;D'FILE
seq 10 |sed '3h;9G;9!d'
sed '$!N;$!D' FILE
sed '$!d' FILE
sed 'G' FILE
sed 'g' FILE

  • awk
    • awk 工作原理和基本用法
    • gawk:模式扫描和处理语言,可以实现的功能
      • 文本处理
      • 输出格式化的文本报表
      • 执行算术运算
      • 执行字符串操作
      • 格式:
        awk [options] ‘program’ var=value file…
常用选项
-f progfile		#从文件中读入
-F fs			#指定分隔符,默认是空白符,可以指定多个
-v var=val		#设置变量

program 用法: program 通常放在单引号中,由三部分组成
	BEGIN{}[pattern]{COMMAND}END{},
awk 'BEGIN{print "begin"}' 	/etc/issue
awk '{print $0}' 			/etc/issue
awk 'END{print "end"}' 		/etc/issue
awk 'BEGIN{print "begin"}{print $0}END{print "end")' /etc/issue

program 格式: pattern{action statements;..}
pattern				#定义条件,只有符合条件的记录,才会执行后边的active				#
action statements	#处理数据的方式,常见的如 printf,print

awk 工作过程
1、执行BEGIN{action;...}语句块中的语句
2、从文件或标准输入(stdin)读取一行,然后执行pattern{action;...}语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕
3、当读至输入流末尾时,执行END{action;...}语句块

分割符、域和记录
文件的每一行称为记录 record
记录可以由指定的分隔符分隔成多个字段(列column,域 field),由$1,$2...$N 来标识每一个字段,$0表示一整行
  • awk 变量
    • 内置变量
      • 常用内置变量
变量名含义
FILENAME当前文件名
FS字段分隔符,默认为空白字符,功能相当于 -F
RS换行符,用于分割指定文件的行,默认是换行符
OFS输出字段分隔符,默认为空白字符
ORS输出换行符,输出时用指定符号代替换行符
OFMT数字的输出格式,默认值是%.6g
NF一条记录的字段数量
NR已经读出的记录数,就是行号,从1开始
FNR各文件分别记录行号
ARGC命令行参数的个数
ARGV数组,保存的是命令行所给定的各个参数,每 一个参数:ARGV[0],…,ARGV[n]
  • 范例
#文件名、变量、分隔符
awk 'BEGIN{print FILENAME}' /etc/issue						#FILENAME, BEGIN拿不到 FILENAME,因为BEGIN语句块不涉及文件和stdin
awk -v FS=":" 'BEGIN{print FS}{print $1FS$1}' /etc/passwd	#FS, $1表示第1个字段,$0表示整行, FS=":"表示用:做分隔符。
awk -F: 'BEGIN{print FS}{print $1FS$1}' /etc/passwd			#-F选项也是指定分隔符,效果和 -v FS=":" 一样
str=":"; awk -v FS=$str 'BEGIN{print FS}{print $1FS$1}' /etc/passwd	#从shell 变量中获取分隔符的值
awk -F":" -v FS=";" 'BEGIN{print FS}' /etc/passwd			#-F和FS变量功能一样,同时使用后面会覆盖前面的
df -h | awk -F" +|%" '{print $5}'|tail -n $(echo `df |wc -l`-1|bc)|sort -nr|head -1 #取分区利用率最高的第一行记录
awk -v RS=";" '{print $0}' test.txt							# RS指定换行符是分号;
awk -v FS=":" -v OFS="---" '{print $1,$3}' /etc/passwd		# OFS 指定输出字段的分隔符用 --- 替换原来的空白符
awk -v ORS="---" '{print $0}' test.txt						# ORS 指定输出换行符用 --- 替换原来的空白符
awk 'BEGIN{PI=3.1415926;print PI;OFMT="%.1g";print PI;OFMT="%.2g";print PI;OFMT="%.8g";print PI;OFMT="%.8f";print PI}'
															# OFMT="%.1g" 指定小保留位数
awk -v FS=":" '{print NF}' /etc/passwd						# NF 一条记录的字段的个数,
awk -v FS=":" '{print $(NF-1)}' /etc/passwd					# $NF,$(NF-1)得到 第几个字段
awk '{print NR,$0}' /etc/issue								# NR,已经读出的记录数,行号从1开始
awk '{print NR,FNR,$0}' /etc/issue /etc/os-release			# FNR,各文件分别记录行号
awk 'BEGIN{print ARGC}' /etc/issue /etc/os-release			# ARGC,命令行参数的个数
awk 'BEGIN{print ARGC,"---",ARGV[0],"---",ARGV[1],
"---",ARGV[2],"---",ARGV[3]}' /etc/issue /etc/os-release	# ARGV,数组。ARGV[0]表示第一个参数,以此类推。
    • 自定义变量:
      • AWK中的自定义变量命令要区分大小写
      • 用-v 选项定义自定义变量
	awk -v var1=abc 'BEGIN{print var1}'
	#在program 中定义, 变量值要加双引号
	awk -v var1=abc 'BEGIN{print var1;var1="def";print var1}{print var1}' /etc/redhat-release	 
  • 动作print
    • 格式:print item1,item2 …
    • 说明:
      • 逗号分隔符,
      • 输出item可以是字符串,也可以是数值;当前记录的字段、变量或awk 的表达式
      • 如省略item ,相当于print $0
        -固定字符串需要用“”引起来,而变量和数字不需要
        awk ‘BEGIN{print “hello world”}’
        awk ‘BEGIN{print 2*3}’
        awk ‘BEGIN{print $0}’
  • 动作printf:可以实现格式化输出
    • 格式:printf “FORMAT” ,item1,item2,…
    • 说明:
      • 必须指定 FORMAT;
      • 不会自动换行,需要显示给出换行控制符\n ;
      • FORMAT中需要分别为后面每个item指定格式符
    • 格式符: 与item 一 一对应
%s			#显示字符串
%d|%i		#显示十进制整数
%f			#显示为浮点数
%e\%E		#显示科学计数法数值
%c			#显示字符的ASCII码
%g|%G		#以科学计算法或浮点形式显示
%u			#无符号整数
%%			#显示%自身

#修饰符
M[.N]	%3.1f		#M表示显示的宽度;N表示小数点后精度
-					#左对齐(默认右对齐)如 %-15s
+					#显示数据的正负符号
awk -F: '{printf "%s",$1}' /etc/passwd		#这样输出没有换行
awk -F: '{printf "%s\n" ,$1}' /etc/passwd		#手动添加换行号
  • 操作符
    • 赋值操作:=,+=,-=,*=,/=,%=, ^=,++,–
    • 比较操作:==,!=, >, >=,<,<=
    • 算术运算符:x+y, x-y, x*y, x/y,x^y, x%y,
      -x #转换为负数
      +x #将字符串转换为数值
    • 逻辑操作符: && || !
    • 三目运算:awk ‘$2>=60?type=“pass”:type=“nopass”{print $1,type}’
  • 模式PATTERN:
    • 根据 pattern 条件过滤匹配的行,再做处理,如果没有指定,则匹配每一行
	awk 'NR==1{print $0}' /etc/issue	#NR 行号为1的时候输出
	
	#用正则匹配,正则表达式需要用 / /来锚定开始结束
	awk '/^UUID/{print $1}' /etc/fstab	#以UUID开头的行,输出第1个字段
	awk '!/^$|^#/{print $1}' /etc/fstab	#匹配非空行和非注释行
	
	#关系表达式:结果为“真”才会被处理。(结果为非0值,非空字符串即为真)
	awk -F: '$3>=1000{print $1,$3}' /etc/passwd		#匹配UID大于等于1000的行,输出非系统用户
	awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd	#匹配有/bin/bash字段的行并输出第1个字段和这个匹配字段
  • 行范围:
    不支持直接用行号,但可以使用变量NR间接指定行号,也可以用正则锚定开始结束行
    • awk ‘NR>=3 && NR<6{print NR,$0}’ /etc/passwd
    • sed -n ‘3,5p’ /etc/passwd
    • awk ‘/^bin/, /^adm/’ /etc/passwd
  • BEGIN/END模式
    • BEGIN{}:仅在开始处理文件中的文本之前执行一次
    • END{}:仅在文本处理完成之后执行一次
    • awk ‘BEGIN{print “begin”}{print $0}END{print “end”}’ /etc/issue
  • 条件判断 if-else
  • awk -F: ‘{if($3<=100){print “<=100”,$3}else if ($3<=1000){print “<=1000”,$3} else{print “>1000”,$3}}’ /etc/passwd
  • 条件判断 switch-case
    • 只能进行等值比较或正则匹配,各分支结尾需使用 break 来终止
  • 循环 while
  • 循环 do-while
  • 循环 for
  • continue 和 break:
    • continue 中断本次循环
    • break 中断整个循环
  • next:可以提前结束对本行处理而直接进入下一行处理
  • awk -F: ‘{if($3%2!=0){next;}; print $1,$3}’ /etc/passwd
  • 数组
  • awk 函数
  • 常见内置函数:
    • 数值处理:
    • rand() 返回0和1之间一个随机数:awk ‘BEGIN{srand();print rand()}’
    • srand(),配合 rand() 函数,生成随机数的种子
    • int() ,返回整数:
    • 字符串处理:
    • length():返回指定字符口中的长度:
    • sub(r,s,[t]): 在 t 中串搜索 r 匹配的内容,并将第一个匹配内容替换为 s
    • gsub(r,s,[t]):在 t 中串搜索 r 匹配的内容,并将匹配内容全部替换为s, 即 贪婪模式
    • split (s,array,[r]) 以 r 为分隔符,切割串 s ,并将结果保存至 array数组中,索引值为1,2,
  • awk 脚本
    • 将awk程序写成脚本,直接调用或执行
4) 格式化输出 printf

4、总结文本处理的grep命令相关的基本正则和扩展正则表达式。

  • 正则表达式
字符匹配
.			#匹配任意单个字符
[]			#匹配指定范围内任意单个字符
[^]			#匹配指定范围外任意单个字符
[:alnum:]	#字母和数字
[:alpha:]	#代表任何英文大小写字符(A-Z),a-z
[:lower:]	#小写字母
[:upper:]	#大写字母
[:blank:]	#空白字符(空格和Tab)
[:space:]	#包括空格、制表符、换行符、回车符等
 
 匹配次数
 * 				#匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 				#任意长度的任意字符
\? 				#匹配其前面的字符出现0次或1次,即:可有可无
\+ 				#匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
\{n\} 			#匹配前面的字符n次
\{m,n\} 		#匹配前面的字符至少m次,至多n次
\{,n\} 			#匹配前面的字符至多n次,<=n
\{n,\} 			#匹配前面的字符至少n次

 位置锚定
^ 			#行首锚定, 用于模式的最左侧
$ 			#行尾锚定,用于模式的最右侧
^PATTERN$ 	#用于模式匹配整行
^$ 			#空行
^[[:space:]]*$ #空白行
\<\b 	#词首锚定,用于单词模式的左侧
\>\b 	#词尾锚定,用于单词模式的右侧
\<PATTERN\> #匹配整个单词

 分组
 () 将多个字符捆绑在一起,当作一个整体处理,如:(root)+
 后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名
方式为: \1, \2, \3,
echo "abcdefabc" | grep "\(abc\)def\1"	#\1表示引用第一个分组的内容
grep -v '^\(#\|$\)' /etc/apache2/apache2.conf #特殊字符要用\转义
  • 扩展正则表达式

grep -Ev '^$|^#' /etc/fstab

5、sed将文件test中第50行中的helloworld改为nihao

cat -n test #查看文件内容,并显示行号
在这里插入图片描述
sed -i.bak '50s/helloworld/nihao/g' test #执行修改同时备份
在这里插入图片描述

7、在每一行后增加一空行(测试文件 cp /etc/passwd /root)

sed -En 's/$/\n/p' /root/passwd #输出到屏幕检查效果
sed -r -i.bak 's/$/\n/g' passwd #执行修改同时备份

在这里插入图片描述

8、删除文件每行的第一个字符。

cat test· #查看文件原始内容
在这里插入图片描述
sed -E -n 's/^.//gp' test #输出到屏幕查看效果
在这里插入图片描述
sed -E -i.bak 's/^.//g' test #修改同时备份
在这里插入图片描述

9、删除文件每行的第二个字符

sed -r -i.bak 's/^(.)(.)/\1/g' test #执行修改同时备份
在这里插入图片描述

10、删除文件每行的最后一个字符

sed -E -n 's/.$//gp' test #输出到屏幕检查效果
sed -E -i.bak 's/.$//g' test #执行修改同时备份
在这里插入图片描述

11、删除文件每行的倒数第二个字符

sed -r -i.bak 's/(.)(.)$/\2/g' test #执行修改同时备份
查找行尾两个字符,并进行分组。使用第2个分组即最后一个字符,替换最后两个字符,即实现了删除倒数第二个字符。
在这里插入图片描述

12、总结变量命名规则,不同类型变量(环境变量,位置变量,只读变量,局部变量,状态变量)如何使用。

1)变量命名规则
  • 命名要求:
    • 区分大小写;
    • 不能使用程序中的保留字和内置变量,如:if,for;
    • 只能使用数字、字母及下划线,且不能以数字开头,不支持短横线“-”
  • 命名习惯:
    • 见名知义,用英文单词命名,并体现出实际作用,不要用简写,如:ATM
    • 变量名大写
    • 局部变量小写
    • 函数名小写
    • 大驼峰:多个单词组成,每个单词的首字母大写,其它小写
    • 小驼峰:多个单词组成,第一个单词的首字母小写,后续单词的首字母大写,其它小写
    • 下划线: student_first_name
2) 变量的定义和引用
  • 变量类型划分(按变量的生效范围)
    • 普通变量:生效范围(当前shell进程)
    • 环境变量:生效范围(当前shell进程及其子进程)
    • 本地变量:生效范围(当前shell进程中某代码片断,通常指函数)
  • 变量赋值:
	name='value'		#
	name='root'			#直接字符串
	name="$USER"		#变量引用
	name=`COMMAND`		#命令引用
	name=$(COMMAND) 	#命令引用

注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除

  • 变量引用:
    • 弱引用:“$name" ,其中的变量引用会被替换为变量值
    • 强引用:‘$name’ ,其中的变量引用不会被替换为变量值,而保持原字符串
    • 显示已定义的所有变量: set
    • 删除变量:unset < name >
  • 环境变量
    • 可以使子进程继承父进程的变量,但无法让父进程使用子进程的变量
    • 一旦子进程修改从父进程继承的变量,会将新的值传递给孙子进程
    • 一般只在系统配置文件中使用,很少在脚本中使用环境变量
    • 变量声明和赋值:
      • export name=VALUE; declare -x name=VALUE #声明并赋值
      • name=VALUE
      • export name #分步实现
    • 变量引用: $name ${name}
    • bash内建的环境变量:
      • PATH、SHELL、USER、UID、 HOME、PWD、SHLV(shell 的嵌套层数,深度)、LANG、MAIL、HOSTNAME、HISTSIZE、
      • _ --------下划线,表示前一命令的最后一个参数
  • 只读变量
    • 只读变量只能声明定义,但后续不能修改和删除,即常量
    • 声明只读变量: readonly name | declare -r name
    • 查看只读变量: readonly [-p] | declare -r
  • 位置变量
    • 在bash shell中内置的变量,在脚本代码中调用通过命令行传递给脚本的参数
	$1,$2,...	#对应第1个,第2个等参数,shift [n]换位置
	$0			#命令本身,包括路径
	$*			#传递给脚本的所有参数,全部参数合为一个字符串
	$@			#传递给脚本的所有参数,每个参数为独立字符串
	$#			#传递给脚本的参数的个数
  • 退出状态码变量
    • $?
    • 0代表成功,1-255 代表失败
    • 自定义退出状态码: exit [n]
    • 注意:
      • 脚本中一旦遇到 exit 命令,脚本会立即终止;终止退出状态取决于 exit 命令后面的数字 exit [n]
      • 如果exit后面无数字,终止退出状态取决于exit 命令前面一条命令执行的结果
      • 如果没有 exit 命令,即末给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

13、通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?

#定义两个变量接收头和脚的数量
HEAD=$1
FOOT=$2
#公式
RABBIT=$[(FOOT-HEAD-HEAD)/2]
CHOOK=$[HEAD-RABBIT]
echo RABBIT: $RABBIT
echo CHOOK:  $CHOOK

#执行脚本,输入两个参数,头30,脚80
./rabb.sh 30 80
#得到结果
RABBIT:10
CHOOK:20

14、结合编程的for循环,条件测试,条件组合,完成批量创建100个用户

在这里插入图片描述

#定义目录和文件的完整路径
DATADIR='/data'
PWFILE="$DATADIR/user.log"

#检查目录是否存在,如果不存在则创建(使用组合测试条件)
[ ! -d "$DATADIR" ] && mkdir -p "$DATADIR" && echo "目录 $DATADIR 已创建"


#检查文件是否存在于目录中,如果不存在则创建文件用于保存用户与密码信息(使用条件测试)
if [ ! -f "$PWFILE" ]; then 
     touch "$PWFILE"
     printf "%-10s %1s %-10s \n" 'username':'password' > "$PWFILE"
     echo "用户名和密码保存在 $PWFILE 文件中"
fi

#提示文件保存位置
echo "用户名和密码保存在 $PWFILE 文件中"

#循环创建用户,并给新创建的用户设置随机12位的密码。
for i in {1..100};do
    USERNAME="user$i"
    if id "$USERNAME" &> /dev/null; then
        echo "用户 $USERNAME 已经存在" 
        continue
    else
        useradd $USERNAME
        echo "用户 $USERNAME 创建成功" 
        PASS=`cat /dev/urandom | tr -dc '[:alnum:]' |head -c12`
        echo $PASS | passwd --stdin $USERNMAE &> /dev/null
        echo $USERNAME:$PASS >> $PWFILE
    fi  
done

执行脚本显示 user1 2 3 7 8 9 10 已经存在,其他用户创建成功
在这里插入图片描述
查看密码文件,没有为已经存在的用户生成密码。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值