一、文本处理工具
查看类常用命令:
1.cat
命令所在路径:/bin/cat
执行权限:所有用户
功能描述:标准输出显示文件内容
语法:cat [OPTION]... [FILE]...
选项:
-n 对显示的每一行进行编号
-b 对显示的非空行进行编号
-E 显示行结束符$
范例1:
查看某个文件的内容
命令:cat anaconda-ks.cfg
范例2:
结合重定向输出文本内容,如果文件已存在则只是将新内容追加到最后而不会覆盖原有的内容。
命令:cat << EOF >> numer.txt
...
结尾以EOF结束
2.more
命令所在路径:/bin/more
执行权限:所有用户
功能描述:分页显示文件内容
语法:more [FILE]...
指令:
h or ? 显示帮助信息
空格键 翻下一页
b 翻上一页
回车键 翻下一行
q or Q 退出分页显示模式
范例1:
分页显示某个文件的内容
命令:more /etc/services
...
3.less
命令所在路径:/bin/less
执行权限:所有用户
功能描述:分页查看文件或标准输出
语法:less [FILE]...
指令:
h or ? 显示帮助信息
空格键 翻下一页
b 翻上一页
回车键 翻下一行
q or Q 退出分页显示模式
/string 搜索匹配的字符串,n 查找下一个,N 查找上一个
范例1:
分页显示某个文件的内容
命令:less /etc/services
...
4.head
命令所在路径:/bin/head
执行权限:所有用户
功能描述:查看文件显示前n行,不带选项默认为前10行
语法:head -n [FILE]...
选项:
-c 获取前n字节
范例1:
查看某个文件前5行的内容
命令:head -5 /etc/services
执行结果:
# /etc/services:
# $Id: services,v 1.55 2013/04/14 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2013-04-10
5.tail
命令所在路径:/bin/tail
执行权限:所有用户
功能描述:查看文件显示后n行,不带选项默认为前10行
语法:tail -n [FILE]...
选项:
-f 跟踪显示文件追加的内容
范例1:
查看某个文件后5行的内容
命令:tail -5 /etc/services
执行结果:
com-bardac-dw 48556/tcp # com-bardac-dw
com-bardac-dw 48556/udp # com-bardac-dw
iqobject 48619/tcp # iqobject
iqobject 48619/udp # iqobject
matahari 49000/tcp # Matahari Broker
范例2:
动态显示某个文件追加的内容
命令:tail -f /var/log/messages
执行结果:
Apr 26 11:01:01 www systemd: Created slice User Slice of root.
Apr 26 11:01:01 www systemd: Started Session 90 of user root.
...
按crtl + c组合键可退出
过滤统计类常用命令:
1.grep
命令所在路径:/usr/bin/grep
执行权限:所有用户
功能描述:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行。
语法:grep [OPTIONS] PATTERN [FILE...]
选项:
-v 反选
-A 显示匹配关键字后面的后n行
-B 显示匹配关键字的前n行
-C 显示匹配关键字的前后n行
-e 指定包含多个or关键字
-E 使用扩展的正则表达式
-W 匹配整个单词
-F 直接搜索,不支持正则表达式;等价于fgrep
-f 指定格式文件
范例1:
过滤输出某个文件中匹配关键字的行内容
命令:grep root /etc/passwd
执行结果:
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
范例2:
通过nmap根据指定的网段进行扫描,结合grep过滤输出显示已启动的主机
命令:nmap -v -sP 172.16.77.0/24 |grep -B1 'is up'
执行结果:
Nmap scan report for 172.16.77.1
Host is up (0.00017s latency).
--
Nmap scan report for 172.16.77.2
Host is up (0.00024s latency).
--
Nmap scan report for 172.16.77.254
Host is up (0.00017s latency).
--
Nmap scan report for 172.16.77.131
Host is up.
2.wc
命令所在路径:/usr/bin/wc
执行权限:所有用户
功能描述:收集文本统计数据
语法:wc [OPTIONS] [FILE...]
选项:
-l 只计数行数
-w 只计数单词总数
-c 只计数字节总数
-m 只计数字符总数
-L 显示文件中最长行的长度
范例1:
统计出/etc/passwd文件中其默认shell为非/sbin/nologin的用户个数
命令:grep -v '/sbin/nologin' /etc/passwd |wc -l
执行结果:
21
范例2:
统计某个文件的单词总数
命令:wc -w ~/number.txt
执行结果:
7 /root/number.txt
3.sort
命令所在路径:/usr/bin/sort
执行权限:所有用户
功能描述:文本排序
语法:sort [OPTIONS] [FILE...]
选项:
-r 执行反方向(由上至下)整理
-R 随机排序
-n 执行按数字大小整理
-f 选项忽略(fold)字符串中的字符大小写
-u 选项(独特,unique)删除输出中的重复行
-t c 选项使用c做为字段界定符
-k X 选项按照使用c字符分隔的X列来整理能够使用多次
范例1:
指定:为分隔符,以:分隔的第3列作为条件将UID倒序排列,显示用户信息
命令:getent passwd |sort -t: -k 3 -nr
执行结果:
xxx666:x:2014:2014::/home/xxx666:/bin/bash
xxx:x:2013:2013::/home/xxx:/bin/bash
y666:x:2012:2012::/home/y666:/bin/bash
z666:x:2011:2011::/home/z666:/bin/bash
...
4.cut
命令所在路径:/usr/bin/cut
执行权限:所有用户
功能描述:剪切显示文本内容
语法:cut [OPTIONS1] [OPTIONS2] [FILE...]
选项:
-d 指定分隔符
-f 第n个字段,多个字段组合使用逗号,隔开
-c 按字符串切割
范例1:
指定:为分隔符,以:分隔的第1列作为条件显示出/etc/passwd文件中其默认shell为非/sbin/nologin的用户
命令:grep -v '/sbin/nologin' /etc/passwd |cut -d: -f1
执行结果:
root
sync
shutdown
...
范例2:
查出用户UID最大值的用户名、UID及shell类型
命令:sort -t: -k3 -rn /etc/passwd |cut -d: -f 1,3,7 |head -1
执行结果:
xxx666:2014:/bin/bash
5.uniq
命令所在路径:/usr/bin/uniq
执行权限:所有用户
功能描述:去掉连续且重复行的内容
语法:uniq [OPTIONS1] [OPTIONS2]
选项:
-c 统计次数
-d 只显示重复的内容
-u 只显示不重复的内容
范例1:
指定:统计当前连接本机按从大到小排序的前3个远程主机IP连接数
命令:
netstat -nt |tr -s " " : |cut -d: -f6| uniq -c|sort -nr|head -3 |grep -v Foreign
执行结果:
netstat -nt |tr -s " " : |cut -d: -f6| uniq -c|sort -nr|head -3 |grep -v Foreign
...
二、正则表达式
REGEXP,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能
程序支持:grep,sed,awk,vim, less,nginx,varnish等
分两类:
基本正则表达式:BRE
扩展正则表达式:ERE
grep -E, egrep
正则表达式引擎:
采用不同算法,检查处理正则表达式的软件模块
PCRE(Perl Compatible Regular Expressions)
元字符分类:字符匹配、匹配次数、位置锚定、分组
字符匹配:
. 匹配任意单个字符
[] 匹配指定范围内的任意单个字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
[^] 匹配指定范围外的任意单个字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数
* 匹配前面的字符任意次,包括0次
贪婪模式:尽可能长的匹配
.* 任意长度的任意字符
? 匹配其前面的字符0或1次
+ 匹配其前面的字符至少1次
{n} 匹配前面的字符n次
{m,n} 匹配前面的字符至少m次,至多n次
{,n} 匹配前面的字符至多n次
{n,} 匹配前面的字符至少n次
示例:
1.提取指定网口的ip地址信息
命令:ifconfig ens33 |grep -o '[0-9.]\{7,15\}' |head -1
执行结果:
172.16.77.131
2.利用df和grep,取出磁盘各分区利用率,并从大到小排序
命令:df |grep -E -v "^/dev/sr|^/dev/cdrom" |grep -o '[[:digit:]]\+%' |tr -d % | sort -rn
执行结果:
26
9
3
0
0
0
0
位置锚定:定位出现的位置
^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
< 或 \b 词首锚定,用于单词模式的左侧
> 或 \b 词尾锚定,用于单词模式的右侧
<PATTERN> 匹配整个单词
示例:
1.提取操作系统大版本号
命令:grep -o '\<[0-9]\+\>' /etc/redhat-release |head -1
执行结果:
7
分组:() 将一个或多个字符捆绑在一起,当作一个整体处理,如:(root)+
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, ...
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例: (string1(string2))
\1 :string1(string2)
\2 :string2
后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
或者:|
如:a|b a或b
C|cat C或cat
(C|c)at Cat或cat
示例:
1.找出/etc/passwd用户名和shell同名的行
命令:grep "([:]+):.*<\1$" /etc/passwd
执行结果:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
bash:x:2003:2003::/home/bash:/bin/bash
nologin:x:2006:2006::/home/nologin:/sbin/nologin
命令名称:egrep = grep -E
语法:egrep [OPTIONS] PATTERN [FILE...]
扩展正则表达式的元字符:
字符匹配:
. 任意单个字符
[] 指定范围的字符
[^] 不在指定范围的字符
示例:
1.使用正则表达式统计当前连接本机的每个远程主机IP连接数,并按从大到小排序
命令:ss -nt |tr -s " "|cut -d " " -f5 |grep -Eo '[0-9.]{7,15}' |sort -rn |uniq -c
执行结果:
2 172.16.77.1
2 127.0.0.1
三、Shell 脚本介绍
shell脚本是包含一些命令或声明,并符合一定格式的文本文件。提供了编程能力,解释执行。
编程语言的基本结构:
各种系统命令的组合
数据存储:变量、数组
表达式:a + b
语句:if
格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
shell脚本的用途:
- 自动化常用命令
- 执行系统管理和故障排除
- 创建简单的应用程序
- 处理文本或文件
shell脚本的工作过程
第一步:使用文本编辑器来创建文本文件
- 第一行必须包括shell声明序列:#!
示例:#!/bin/bash - 添加注释
注释以#开头
第二步:运行脚本
- 给予执行权限,在命令行上指定脚本的绝对或相对路径
- 直接运行解释器,将脚本作为解释器程序的参数运行
脚本代码开头约定
1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息
6、该程序的作用,及注意事项
7、最后是各版本的更新简要说明
脚本的基本结构
#!SHEBANG
CONFIGURATION_VARIABLES(配置变量)
FUNCTION_DEFINITIONS(功能/函数定义)
MAIN_CODE(主要实现代码)
编辑.vimrc配置文件,添加实现自动生成脚本格式的内容:
set ignorecase
set cursorline
set autoindent
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
if expand("%:e") == 'sh'
call setline(1,"#!/bin/bash")
call setline(2,"#")
call setline(3,"#********************************************************************")
call setline(4,"#Author: zhangxuhao")
call setline(5,"#QQ: 335249105")
call setline(6,"#Date: ".strftime("%Y-%m-%d"))
call setline(7,"#FileName: ".expand("%"))
call setline(8,"#URL: https://www.jianshu.com/u/d1eff6d1a4db")
call setline(9,"#Description: The test script")
call setline(10,"#Copyright (C): ".strftime("%Y")." All rights reserved")
call setline(11,"#********************************************************************")
call setline(12,"")
endif
endfunc
autocmd BufNewFile * normal G
检测脚本中的语法错误
bash -n /path/to/some_script
调试执行
bash -x /path/to/some_script
3.1 变量
定义:命名的内存空间
作用:
1、数据存储方式
2、参与的运算
3、表示的数据范围
类型:字符
数值:整型、浮点型
弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用
如:bash 不支持浮点数,php,javascript
根据变量的生效范围等标准划分下面变量类型
局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
位置变量:$1, $2, ...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?(返回值), $0(本身的文件名), $*(所有参数,一个整体), $@(所有参数,单一分隔),$#(参数个数),$$(本身的PID)
变量声明、赋值:
export name=VALUE
declare -x name=VALUE
变量引用:
$name, ${name}
显示所有环境变量:
env
printenv
export
declare -x
删除变量:
unset name
进程使用退出状态来报告成功或失败
0 代表成功,1-255代表失败
$? 变量保存最近的命令退出状态
3.2 bash算术运算
let命令
+, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义
实现算术运算:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 ...)
(5) declare -i var = 数值
(6) echo ‘算术表达式’ | bc
bash内建的随机数生成器变量:
$RANDOM(0-32767)
增强型赋值:
+=, -=, *=, /=, %=
let var OPER value
例如:let count+=3
自加3后自赋值
自增,自减:
let var+=1
let var++
let var-=1
let var--
3.3 逻辑运算
true(真), false(假)
1 0
与
1 与 1 = 1
1 与 0 = 0
0 与 1 = 0
0 与 0 = 0
或
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非:!
! 1 = 0 ! true
! 0 = 1 ! false
短路运算
短路与
第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
异或:^
异或的两个值,相同为假,不同为真
3.4 条件测试
判断某需求是否满足,需要由测试机制来实现
专用的测试表达式需要由测试命令辅助完成测试过程
评估布尔声明,以便用在条件性执行中
- 若真,则返回0
- 若假,则返回1
测试命令:
•test EXPRESSION
•[ EXPRESSION ]
•[[ EXPRESSION ]]
注:EXPRESSION前后必须有空白字符
3.4.1 bash的数值测试
-v VAR
变量VAR是否设置
数值测试:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
3.4.2 bash的字符串测试
字符串测试:
= 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注:此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING“ 字符串是否为空,空为真,不空为假
-n "STRING“ 字符串是否不空,不空为真,空为假
注:用于字符串比较时的用到的操作数都应该使用引号
3.4.3 bash文件测试
test命令
存在性测试
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
存在性及类别测试
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
文件权限测试:
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
文件特殊权限测试:
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
文件大小测试:
-s FILE: 是否存在且非空
-t fd: fd 文件描述符是否在某终端已经打开,位置:/proc/<pid>/fd
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
双目测试:
FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2
组合测试条件
第一种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行,[[ ]] 不支持
第二种方式:
COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
! COMMAND 非
如:[ -f "$FILE" ] && [[ "$FILE"=~ .*.sh$ ]]
条件性的执行操作符
示例:
grep -q no_such_user /etc/passwd || echo 'No such user'
No such user
ping -c1 -W2 station1 &> /dev/null \
> && echo "station1 is up"
> || (echo 'station1 is unreachable'; exit 1)
station1 is up
bash组合测试条件
示例:
test "$A" = "$B" && echo "Strings are equal"
test "$A"-eq "$B" && echo "Integers are equal"
[ "$A" = "$B" ] && echo "Strings are equal"
[ "$A" -eq "$B" ] && echo "Integers are equal“
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
[ -z "$HOSTNAME" -o $HOSTNAME == "localhost.localdomain" ]
&& hostname www.magedu.com
短路与和短路或
[ [$RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"
3.4.4 read命令接受键盘输入
使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒
read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量
例:read -p “Enter a filename: “ FILE
3.4.5 条件选择if语句
选择执行:
注:if语句可嵌套
单分支
if 判断条件;then
条件为真的分支代码
fi
双分支
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi
示例:编写脚本createuser.sh,实现如下功能适用一个用户名作为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户id号等信息
vi createuser.sh
#!/bin/bash
result=`id $1 &>/dev/null;echo $?`
if [ $result -eq 0 ];then
echo 该用户已存在
else
useradd $1 && id $1
fi
效果:
./createuser.sh zxh666
uid=2015(zxh666) gid=2015(zxh666) groups=2015(zxh666)
./createuser.sh zxh666
该用户已存在
多分支
if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
else
以上条件都为假的分支代码
fi
逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句。
3.4.6 条件判断语句case
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b