shell 编程四剑客

shell 编程四剑客
一、shell 编程四剑客之 find
四剑客之 find 工具实战,find工具主要用于操作系统文件、目录的查找,其语法参数格式:
find        path        -ption        [        -print]        [-exec        -ok        command]        { } \;
其中option常用参数详解如下:
-name filename        查找名为filename的文件
-typeb/d/c/p/l/f        查找块设备、目录、字符设备、管道、符号链接、普通文件
-sizen[c]                查找长度为n块[或n字节]的文件
-perm                        按执行权限来查找
-userusername                按文件属主来查找
-groupgroupname        按文件所属组来查找
-mtime -n +n                按文件更改时间来查找文件,-n指n天以内,+n指n天以前
-atime -n+n                按文件访问时间来查找文件
-ctime -n+n                按文件创建时间来查找文件
-mmin -n+n                按文件更改时间来查找文件,-n指n分钟以内,+n指n分钟以前
-amin -n+n                按文件访问时间来查找文件
-cmin -n+n                按文件创建时间来查找文件
-nogroup                查找无有效属组的文件
-nouser                        查找无有效属主的文件
-newer f1 !f2                查找更改时间比f1新但比f2旧的文件
-depth                        在进入子目录先行查找完本目录
-fstype                        查找此文件系统类型的文件
-mount                        查找文件时不跨越文件系统mount点
-follow                        如果遇到符号链接文件,就跟踪链接所指的文件
-cpio                        查找位于某一类型文件系统中的文件
-prune                        忽略某个目录
-maxdepth                查找目录级别深度
1、find 工具-name 参数案例:
find /data/ -name"*.txt"                查找/data/目录以.txt结尾的文件
find /data/ -name"[A-Z]*"        查找/data/目录以大写字母开头的的文件
find /data/ -name"test*"        查找/data/目录以test开头的文件
2、find 工具-type 参数案例:
find /data/ -typed                查找/data/目录下的文件夹
find /data/ ! -typed                查找/data/目录下的非文件夹
find /data/ -typel                查找/data/目录下的链接文件
find /data/ -typed|xargs chmod 755-R        查找/data/目录下的文件夹并将文件夹权限和里面的文件权限设置为755
find /data/ -type l|xargs chmod 644-R        更改查找类型是文件的权限为644
3、find 工具-size 参数案例:
find /data/ -size+1M                查找大于1MB的文件
find /data/ -size10M                查找等于10MB的文件
find /data/ -size-1M                查找小于1MB的文件
4、find 工具-perm参数案例:
find /data/ -perm755                查找/data/目录权限为755的文件或者目录
find /data/ -perm-007                与-perm777相同,表示所有权限
find /data/ -perm+644                查找文件权限符号为644以上的文件
5、find 工具-mtime参数案例:
find /data/ -mtime +30-name"*.log"        查找30天以前的log文件
find /data/ -mtime -30-name"*.txt"        查找30天以内的txt文件
find /data/ -mtime 30-name"*.txt"        查找第30天的txt文件
find /data/ -mmin +30-name"*.log"        查找30min以前修改的log文件
find /data/ -amin -30-name"*.log"        查找30min以内修改的log文件
find /data/ -cmin 30-name"*.txt"        查找第30min改变的txt文件
6、find 工具参数综合案例:
#查找/data/目录以.log结尾,文件大于10KB的文件,同时cp到/tmp目录:
find /data/ -name"*.log" -type f -size +10K -exec cp {} /tmp/ \;
#查找/data目录以.txt结尾,文件大于10KB的文件,权限为644并删除该文件:
find /data/ -name"*.log" -type f -size +10K -perm 644 -exec rm -rf {} \;
#查找/data目录以.log结尾,30天以前的文件,大小大于10MB并移动到/tmp目录:
find /data/ -name"*.log" -type f -mtime +30 -size +10M -exec mv {} /tmp/ \;
 
二、shell 编程四剑客之sed
sed是一个非交互式文本编辑器,它可对文本文件和标准输入进行编辑,标准输入可以来自键盘、文字重定向、字符串、变量,甚至来自管道文本,与vim编辑器类似,它一次处理一行内容,sed可以编辑一个或多个文件,简化对文件的反复操作、编写转换程序等。
sed        [ -Options]        ['Commands']        filename;
sed工具默认处理文本,文本内容输出屏幕已经修改,但是文件内容其实没有修改,需要加-i参数,即对文件彻底修改。
x                指定行号
x,y                指定x到y的行号范围
/pattern/        查询包含模式的行
/pattern/pattern/        查询包含两个模式的行
/pattern/,x        从与pattern的匹配行到x号行之间的行
x,/pattern/        从x号行到与pattern的匹配行之间的行
x,y!                查询不包括x和y行号的行
r                从另一个文件中读文件
w                将文本写入到一个文件
y                变换字符
q                第一个模式匹配完成后退出
l                显示与八进制ASCII码等价的控制字符
{}                在定位行执行的命令组
p                打印匹配行
=                打印文件行号
a\                在定位行号之后追加文本信息
i\                在定位行号之前插入文本信息
d                删除定位行
c\                用新文本替换定位文本
s                使用替换模式替换相应模式
n                读取下一个输入行,用下一个命令处理新的行
N                将当前读入行的下一行读取到当前的模式空间
h                将模式缓冲区的文本复制到保持缓冲区
H                将模式缓冲区的文本追加到保持缓冲区
x                互换模式缓冲区和保持缓冲区的内容
g                将保持缓冲区的内容复制到模式缓冲区
G                将保持缓冲区的内容追加到模式缓冲区
常用sed工具企业案例:
1、替换tang.txt文本中old为new:
sed 's/old/new/g'tang.txt
2、打印tang.txt文本第一行至第三行:
sed -n '1,3p'  tang.txt
3、打印tang.txt文本中第一行与最后一行:
sed -n '1p;$p' tang.txt
4、删除tang.txt第一行与第三行、删除匹配行至最后一行:
sed '1,3d' tang.txt
sed '/tang/,$d'tang.txt
5、删除tang.txt最后6行及删除最后一行:
for i in `seq 1 6`; dosed -i '$d' tang.txt;done
sed'$d'        tang.txt
6、在tang.txt中查找tang所在行,并在其下一行添加word字符,a表示在其下一行添加字符串:
sed '/tang/aword'tang.txt
7、在tang.txt查找tang所在行,并在其上一行添加word字符,i表示在其上一行添加字符串:
sed '/tang/iword'tang.txt
8、在tang.txt查找以.test结尾的行,在基行尾添加字符串word,$表示结尾标识,&在sed中表示添加:
sed's/\.test$/&word/g' tang.txt
9、在tang.txt查找www的行,在其行首添加字符串word,^表示起始标识,&在sed中表示添加:
sed'/www/s/^/&word' tang.txt
10、多个sed命令组合,使用分号“;”分割:
sed -e'/www.jd.com/s/^/&1./; s/www.jd.com$/&./g' tang.txt
11、多个sed命令组合,使用-e参数:
sed -e'/www.jd.com/s/^/&1./' -e 's/www.jd.com$/&./g' tang.txt
12、sed读取系统变量,进行变量替换:
WEBSITE=WWW.TANG.COM
sed"s/www.jd.com/$WEBSITE/g" tang.txt
13、修改SELinux策略enforcing为disabled,查找/SELINUX/行,然后将其行enforcing值改为disabled,!s表示不包括SELINUX行:
sed -i'/SELINUX/s/enforcing/disabled/g' /etc/selinux/config
sed -i'/SELINUX/!s/enforcing/disabled/g' /etc/selinux/config
通常而言,sed将待处理的行读入模式空间,脚本中的命令逐行进行处理直到脚本执行完毕,然后该行被输出,模式空间清空,然后重复刚才的动作,文件中的新的一行被读入,直到文件处理完备。
sed高级语法:
N、D、P        处理多行模式空间的问题
H、h、G、g、x        将模式空间的内容放入存储空间以便接下来的编辑
:、b、t                在脚本中实现分支与条件结构
1、在tang.txt每行后加入空行,也即每行占用两行空间,每一行后边插入一行空行、两行空行及前三行每行后插入空行:
sed '/^$/d;G'  tang.txt
sed '/^$/d;G;G'tang.txt
sed'/^$/d;1,3G'        tang.txt
2、将tang.txt偶数行删除及隔行删除一行:
sed 'n;d' tang.txt
sed 'n;n;d' tang.txt
3、在tang.txt匹配前一行、后一行插入空行以及同时在匹配前后插入空行:
sed '/tang/{x;p;x;}'tang.txt
sed '/tang/G' tang.txt
sed '/tang/{x;p;x;G;}'tang.txt
4、在tang.txt每行后加入空行,也即每行占用两行空间,每一行后边插入空行:
sed '/^$/d;G' tang.txt
5、在tang.txt每行后加入两行空行,也即每行占用三行空间,每一行后边插入空行:
sed '/^$/d;G;G'tang.txt
6、在tang.txt第行前加入顺序数字序号、加上制表符"\t"及"."符号:
sed = tang.txt |sed'N;s/\n/ /'
sed = tang.txt |sed'N;s/\n/\t/'
sed = tang.txt |sed'N;s/\n/\./'
7、删除tang.txt行前和行尾的任意空格:
sed's/^[\t]*//;s/[\t]*$//' tang.txt
8、打印tang.txt关键词old与new之间的内容:
sed -n '/old/,/new/'ptang.txt
9、打印及删除tang.txt最后两行:
sed '$!N;$!D' tang.txt
sed 'N;$!P;$!D;$d'tang.txt
10、合并上、下两行,也即两行合并:
sed ’$!N;s/\n//‘tang.txt
sed 'N;s/\n//' tang.txt
 
三、shell 编辑四剑客之awk
awk是一个优良的文本处理工具,Linux及UNIX环境中现有的功能最强大的数据处理引擎之一,以Aho、Weinberger、Kernighan三位发明者名字首字母命名为awk,awk是一个行级文本高效处理工具,awk经过改进生成的新的版本有nawk、gawk,一般Linux默认为gawk,gawk是awk的GNU开源免费版本。
awk基本原理是逐行处理文件中的数据,查找与命令行中所给定内容相匹配的模式,如果发现匹配内容,则进行下一个编程步骤,如果找不到匹配内容,则继续处理下一行。
awk  ‘pattern + {action}’  file
@@@ awk常用参数、变量、函数详解:@@@
1、awk基本语法参数详解如下:
单引号‘ ’是为了和shell命令区分开。
大括号{ }表示一个命令分组。
pattern是一个过滤器,表示匹配pattern条件的行才进行action处理。
action是处理动作,常见动作为print。
使用#作为注释,pattern和action可以只有其一,但不能两者都没有。
2、awk 内置变量详解:
FS        分隔符,默认是空格
OFS        输出分隔符
NR        当前行数,从1开始
NF        当前记录字段个数
$0        当前记录
$1~$n        当前记录第n个字段(列)
3、awk 内置函数详解:
gsub(r,s)        在$0中用s代替r。
index(s,t)        返回s中t的第一个位置。
length(s)        s的长度
match(s,r)        s是否匹配r
split(s,a,fs)        在fs上将s分成序列a
substr(s,p)        返回s从p开始的子串
4、awk 常用操作符、运算符及判断符:
++--                增加与减少(前置或后置)
^**                指数(右结合性)
!+-                非、一元(unary)加号、一元减号
+-*/%                加、减、乘、除、余数
<<= == !=>>=      数字比较
&&                逻辑and
||                逻辑or
= += -= *= /= %= ^=**=        赋值
5、awk 与流程控制语句:
if (condition) { } else{ };
while { };
do { } while(condition);
for(init;condition;step){ };
break/continue。
@@@ 常用awk工具企业演练案例:@@@
1、awk打印硬盘设备名称,默认以空格为分割:
df -h | awk '{print$1}'
2、awk 以空格、冒号、\t、分号为分割:
awk -F '[ :\t;]''{print $1}'  tang.txt
3、awk以冒号分割,打印第一列,同时将内容追加到/tmp/awk.log下:
awk -F: ‘{print $1>>"/tmp/awk.log"}’ tang.txt
4、打印tang.txt文件中的第3行至第5行,NR表示打印行,$0表示文本所有域:
awk 'NR==3,NR==5{print}' tang.txt
awk 'NR==3,NR==5 {print$0}'  tang.txt
5、打印tang.txt文件中的第3行至第5行的第一列与最后一列:
awk 'NR==3,NR==5 {print$1,$NF}'  tang.txt
6、打印tang.txt文件中长度大于80的行号:
awk ‘length($0)>80{print NR}’  tang.txt
7、awk引用shell变量,使用-v或者双引号+单引号即可:
awk -v STR=hello'{print STR,$NF}' tang.txt
STR="hello";echo|awk'{print "'$(STR)'";}'
8、awk以冒号切割,打印第一列同时只显示前5行:
cat /etc/passwd|head-5|awk -F: '{print $1}'
awk -F:'NR>=1&&NR<=5 {print $1}' /etc/passwd
9、awk指定文件tang.txt第一列的总和:
cat tang.txt |awk'{sum+=$1}END{print sum}'
10、awkNR行号除以2余数为0则跳过该行,继续执行下一行,打印在屏幕:
awk -F:'NR%2==0{next}{print NR,$1}' /etc/passwd
11、awk 添加自定义字符:
ifconfig eth0 |grep"Bcast" |awk ‘{print "ip_"$2}’
12、awk格式化输出passwd内容,printf打印字符串,%格式化输出分隔符,s表示字符串类型,-12表示12个字符,-6表示6个字符:
awk -F: '{printf"%-12s %-6s %-8s\n",$1,$2,$NF}' /etc/passwd
13、awk OFS输出格式化\t:
netstat -an |awk '$6 ~/LISTEN/&&NR>=1&&NR<=10 {print NR,$4,$5,$6}'OFS="\t"
14、awk 与 if组合实战,判断数字比较:
echo 3 2 1 |awk ‘{if(($1>$2)||($2>$3)) {print $2}else{print $1}}’
15、awk与数组组合实战,统计passwd文件用户数:
awk -F ':''BEGIN{count=0;}{name[count]=$1;count++;};END{for(i=0;i<NR;i++) printi,name[i]}' /etc/passwd
16、awk分析Nginx访问日志的状态码404、502等错误信息页面,统计次数大于20的IP地址:
awk ‘{if($9~/502|499|500|503|404/) print $1,$9}’ access.log|sort|uniq -c|sort -nr|awk'{if($1>20) print $2}'
17、用/etc/shadow文件中的密文部分替换/etc/passwd中的“x”位置,生成新的/tmp/passwd文件:
awk‘BEGIN{OFS=FS=":"} NR==FNR{a[$1]=$2}NR>FNR{$2=A[$1];print>>"/tmp/passwd"}’ /etc/shadow /etc/passwd
18、awk 统计服务器状态连接数:
netstat -an |awk '/tcp/{s[$NF]++}END{for(a in s) {print a,s[a]}}'
netstat -an |awk '/tcp/{print $NF}' |sort |uniq -c
 
四、shell 编程四剑客之grep
全面搜索正则表达式(grep)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
UNIX/Linux的grep家族包括grep、egrep和fgrep,其中egrep和fgrep的命令跟grep有细微的区别,egrep是grep的扩展,支持更多的re元字符,fgrep是fixedgrep或fast grep的简写,它们把所有的字母都看作单词,正则表达式中的元字符表示其自身的字面意义,不再有其他特殊的含义。
目前Linux操作系统默认使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。
grep -[acinv] 'word'filename
grep常用参数详解:
-a        以文本文件方式搜索
-c        计算找到的符合行的次数
-i        忽略大小写
-n        顺便输出行号
-v        反向选择,即显示不包含匹配文本的所有行
-h        查询多文件时不显示文件名
-l        查询多文件时只输出包含匹配字符的文件名
-s        不显示不存在或无匹配文本的错误信息
-E        允许使用egrep扩展模式匹配
通配符类型详解:
*        0个或者多个字符、数字。
?        匹配任意一个字符。
#        表示注解
|        管道符号
;        多个命令连续执行
&        后台运行指令
!        逻辑运算非
[]        内容范围,匹配括号中内容
{}        命令块,多个命令匹配
正则表达式详解:
*        前一个字符匹配0次或多次
.        匹配除了换行符以外任意一个字符
.*        代表任意字符
^        匹配行首,即以某个字符开头
$        匹配行尾,即以某个字符结尾
\(..\)        标记匹配字符
[]        匹配中括号里的任意指定字符,但只匹配一个字符
[^]        匹配除中括号以外的任意一个字符
\        转义符,取消特殊含义
\<        锚定单词的开始
\>        锚定单词的结束
{n}        匹配字符出现n次
{n,}        匹配字符出现大于等于n次
{n,m}        匹配字符至少出现n次,最多出现m次
\w        匹配文字和数字字符
\W        \w的反置形式,匹配一个或多个非单词字符
\b        单词锁定符
\s        匹配任何空白字符
\d        匹配一个数字字符,等价于[0-9]
常用grep工具企业演练案例详解:
grep -c"test"tang.txt                统计test字符总数
grep -i"TEST"tang.txt                不区分大小写查找test所有的行
grep -n"test"tang.txt                打印test的行及行号
grep -v"test" tang.txt                不打印test的行
grep"test[53]"tang.txt                以字符test开头,接5或者3的行
grep"^[^test]"tang.txt                显示输出行首不是test的行
grep"^[Mm]ay"tang.txt                匹配M或m开头的行
grep "K...D"tang.txt                匹配K,三个任意字符,紧接D的行
grep"[A-Z][9]D"tang.txt                匹配大写字母,紧跟9D的字符行
grep"T\{2,\}"tang.txt                打印字符T字符连续出现2次以上的行
grep"T\{4,6\}"tang.txt                打印字符T字符连续出现4次及6次的行
grep -n "^$"tang.txt                打印空行的所在的行号
grep --color -ra -E"db|config|sql" * 匹配包含db或者config或者sql的文件
grep -vE “#|^$”                        不匹配文件中的#和空行
grep --color -E"\<([0-9]{1,3}\.){3}([0-9]{1,3})\>"tang.txt        匹配IPv4地址
 
五、shell 数组编程
数组是相同数据类型的元素按一定顺序排列的集合,把有限个类型相同的变量用一个名字命名,然后用编号区分它们变量的集合,这个名称即为数组名。编号即为下标。Linuxshell编程中常用一维数据。数组的设计实际上是为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式,以减少重复频繁的单独定义。定义数组一般以小括号的方式来定义,数组的值可以随机指定,以下为一维数组的定义,数组的值可以随机指定,以下为一维数组的定义、统计、引用和删除操作详解。
1、一维数组定义及创建:
JFTEST=(
test1
test2
test3
)
LAMP=(httpd phpphp-devel php-mysql mysql mysql-server)
2、数组下标一般从0开始,引用数组的方法详解:
echo${JFTEST[0]}        引用第一个数组变量,结果打印test1
echo${JFTEST[1]}        引用第二个数组变量,结果打印test2
echo${JFTEST[@]}        显示该数组所有参数
echo${#JFTEST[@]}        显示该数组参数个数
echo${#JFTEST[0]}        显示test1字符长度
echo${JFTEST[@]:0}        打印数组所有的值
echo${JFTEST[@]:1}        打印从第二个值开始的所有值
echo${JFTEST[@]:0:2}        打印第一值与第二个值
echo${JFTEST[@]:1:2}        打印第二个值与第三值
3、数组替换操作:        
3、数组替换操作:        
TEST=([0]=www1 [1]=www2[2]=www3)        数组赋值
echo${TEST[@]/test/tang}                将数组值test 替换为tang
NEWTEST='echo${TEST[@]/test/tang}'        将结果赋值新数组
4、数组删除操作:
unsetarray[0]                删除数组第一个值
unsetarray[1]                删除数组第二个值
unsetarray                删除整个数组
5、数组shell脚本企业案例,网卡bond绑定脚本:
#!/bin/bash
#Auto Make KVMVirtualization
#Auto config bondscripts
#By author tang.com2018
eht_bond()
{
NETWORK=(
HWADDR='ifconfigeth0|egrep "HWaddr|Bcast"|tr "\n" " "|awk '{print$5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g' |awk '{print $1}''
IPADDR='ifconfigeth0|egrep "HWaddr|Bcast"|tr "\n" " "|awk '{print$5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g' |awk '{print $2}''
NETMASK='ifconfigeth0|egrep "HWaddr|Bcast"|tr "\n" " "|awk '{print$5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g' |awk '{print $3}''
GATEWAY='route-n|grep "UG"|awk '{print $2}''
)
cat > ifcfg-bond0<<EOF
DEVICE=bond0
BOOTPROTO=static
${NETWORK[1]}
${NETWORK[2]}
${NETWORK[3]}
ONBOOT=yes
TYPE=Ethernet
NM_CONTROLLED=no
EOF
}