shell

Shell

Shell编写规范

开头指定脚本解释器

​ #!/bin/sh或#!/bin/bash
​ 其他行#表示注释
​ 名称见名知义 backup_mysql.sh,以sh结尾

#comment1
#comment2
#comment3
...
#如何实现多行注释?
#用户还可以通过其他的一些变通的方法来实现多行注释,其中,最简单的方法就是使用冒号“:”配合heredocument,语法如下
:<<BLOCK
....注释内容
#开头加版本版权等信息
BLOCK
# Date:创建日期
# Author:作者
# Mail:联系方式
# Function:功能
# Version:版本  

SHELL常见的系统变量解析

$0 当前程序的名称
$n 当前程序的第 n 个参数 ,n=1,2, , 9
$* 当前程序的所有参数 ( 不包括程序本身 )
$# 当前程序的参数个数 ( 不包括程序本身 )
$? 命令或程序执行完后的状态,一般返回 0 表示执行成功。
$UID 当前用户的 ID
$PWD 当前所在的目录

逻辑运算符解析
-f 判断文件是否存在 eg: if [ -f filename ]
-d 判断目录是否存在 eg: if [ -d dir ]
-eq 等于 应用于:整型比较
-ne 不等于 应用于:整型比较
-lt 小于 应用于:整型比较
-gt 大于 应用于:整型比较
-le 小于或等于 应用于:整型比较
-ge 大于或等于 应用于:整型比较
-a 双方都成立( and) 逻辑表达式 –a 逻辑表达式
-o 单方成立( or) 逻辑表达式 –o 逻辑表达式
-z 空字符串

循环语句 while
while 条件语句
do
语句 1
done

Until 循环语句
until 条件
do
action
done
直到满足条件,才退出。否则执行 action 。

shell 允许将一组命令集或语句形成一个可用块,这些块称为
shell 函数,定义函数的格式:
function name (){
command1

}
name

Shell 数组编程

定义数组一般以括号的方式来定义

echo ${A[@]} 将显示所有参数

echo ${A[#@]} 将显示参数个数

${A[@]/test2/test5} test5替换test2

unset A[i]删除第i个

bash常用快捷键

ctrl+c键盘中断请求,终止当前的命令

ctrl+s ctrl+q暂停/恢复屏幕输出

ctrl+l清屏,相当于clear

ctrl+u删除光标至行首的内容

ctrl+k删除光标至行尾的内容

Ctrl+a    跳到命令行行首

Ctrl+e    跳到命令行行尾

ctrl+左右箭头,支持按单词跳转

输入输出重定向

  • Bash的标准输入输出
设备 		设备文件名 		文件描述符 		类型
键  盘 	 /dev/stdin 	 0 			 标准输入
显示器 	/dev/stdout 	 1 			标准输出
显示器 	/dev/stderr 	 2 		    标准错误输出
  • 输出重定向
类型符号作用
标准输出重定向命令 > 文件以覆盖的方式,把命令的正确输出输出到指定的文 件或设备当中
命令 >> 文件以追加的方式,把命令的正确输出输出到指定的文 件或设备当中
标准错误输出重定向错误命令 2> 文件以覆盖的方式,把命令的错误输出输出到指定的文 件或设备当中
错误命令2 >>文件以追加的方式,把命令的错误输出输出到指定的文 件或设备当中
正确输出和错误输出同时保存命令 >文件 2>&1以覆盖的方式,把正确输出和错误输出都保存到同 一个文件当中
命令 >>文件 2>&1以覆盖的方式,把正确输出和错误输出都保存到同 一个文件当中
命令 &>文件以覆盖的方式,把正确输出和错误输出都保存到同 一个文件当中
命令 &>>文件以追加的方式,把正确输出和错误输出都保存到同 一个文件当中
命令>>文件1 2>>文件2把正确的输出追加到文件 1 中,把错误的输出追 加到文件 2 中
; --命令的顺序执行
date ; ls -l /etc/passwd
&& --前面命令执行不成功,后面的命令不执行
mkdir /mnt/iso && mount /dev/sr0 /mnt/iso
|| --如果前面命令成功,后面就不执行,如果前面不成功后面就执行

通配符

? 匹配一个任意字符
`*` 匹配 0 个或任意多个任意字符,也就是可以匹配任何内容
[] 匹配中括号中任意一个字符。
[-] 匹配中括号中任意一个字符, -代表一个范围。
[^] 逻辑非,表示匹配不是中括号内的一个字符。
  • 通配符常用语法
1、*:匹配任意长度的任意字符,就是说“什么都可以”。
/etc/fs* #/etc中以fs开头的文件将被匹配
/tmp/my*1 #/tmp中以my开头并且以1结尾的文件将被匹配
2、?:与任何单个字符匹配。
myfile? #文件名为myfile且后面跟任一单个字符的任何文件将被匹配
/tmp/notes?txt #如果/tmp/notes.txt和/tmp/notes_txt都存在的话他们都会被匹配
3、[ ]:与?相似,可以匹配一个括号内的字符,也可以用“-”进行范围指定。
myfile[12] #将与myfile1和myfile2匹配
[Cc]hange[Ll]og #Changelog、ChangeLog、changeLog以及changelog都可匹配,与大写形式的
变形匹配时,使用括弧通配符很有用
ls /etc/[0-9] #将列出 /etc 中以数字开头的所有文件。
ls /tmp/[A-Za-z] #将列出/tmp中以大写字母或小写字母开头的所有文件。
4、[!]:括号内的“!”代表非的意思,即不与括弧中的字符匹配。
rm myfile[!9] #删除除了myfile9之外的名为myfile加一个字符的所有文件
5、{}生成序列
touch file{1..9}.txt #当前路径生成file1.txt~file9.txt。{a..f}代表a-f,不连续的使用,分
隔,比如f{1,3,5}.txt
6、使用{}备份
cp file1.txt{,.bak} #将fiel1.txt复制一份叫file1.txt.bak
cp file{2,22}.txt #复制file2.txt为file22.txt


#示例
1、列出/etc/目录中不是以字母a到n开头的,并且以.conf结尾的文件
ls /etc/[!a-n]*.conf
2、列出/etc/目录中以字母a到n开头的,并且以.conf结尾的文件
ls /etc/[a-n]*.conf
3、列出/bin/下以 c或k开头的文件名
ls /bin/[ck]*

同时有w和x权限才可以创建、删除文件和目录

权限(删除文件由文件的上层目录控制,跟文件本身的权限无关。)

shell基本元素

Shell脚本的第一行通常为如下内容:

#!/bin/bash //第一行

Shell脚本的第一行均包含一个以**#!为起始标志的文本行,这个特殊的起始标志表示当前文件包含一组命令,需要提交给指定的Shell解释执行。紧随#!**标志的是一个路径名,指向执行当前Shell脚本文件的命令解释程序

shell正则表达式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fZ1qyYXN-1601295214234)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200807112316647.png)]

shell特殊字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pXplFZT3-1601295214236)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200807113752895.png)]

变量和引号

Shell语言中一共有3种引号,分别为
单引号(’ ‘)单引号括起来的字符都作为普通字符出现
双引号(" ")双引号括起来的字符,除“$”、“\”、“’”和“"”这几个字符仍是特殊字符并保留其特殊功能
外,其余字符仍作为普通字符对待,
反引号(``)。反引号括起来的字串被Shell解释为命令,在执行时,Shell首先执行该命令,并以它
的标准输出结果取代整个反引号(包括两个反引号)部分

符号说明
双引号除美元符号、单引号、反引号和反斜线之外,其他所有的字符都将保持字面意义
单引号所有的字符都将保持字面意义
反引号反引号中的字符串将被解释为Shell命令
反斜线转义字符,屏蔽后的字符的特殊意义
[root@localhost ~]# echo "current_user is: $USER"
current_user is: root
[root@localhost ~]# echo 'current_user is: $USER'
current_user is: $USER
[root@localhost ~]# echo "current_user is: `whoami`"
current_user is: root
[root@localhost ~]# echo 'current_user is: `whoami`'
current_user is: `whoami`

赋值前后不能又空格否则会报错

  • 内部变量

PWD:表示当前的工作目录,其变量值等同于pwd内部命令的输出。

RANDOM:每次引用这个变量时都会生成一个均匀分布的0~32767范围内的随机整数。

SCONDS:脚本已经运行的时间(单位:秒)。

PPID:当前进程的父进程的进程ID。

$?:表示最近一次执行的命令或shell脚本的出口状态

  • 环境变量

EDITOR:用于确定命令行编辑所用的编辑程序,通常为vim。

HOME :用户主目录。

PATH:指定命令的检索路径

**Linux中含有两个重要的文件:/etc/profile和KaTeX parse error: Expected group after '_' at position 11: HOME/.bash_̲_profile,每当系统登录…HOME/.bash_profile是每个用户自己独立的,可以通过修改该文件来设置PATH变量。如果要让所有用户都能用到此PATH变量,可以用vim命令打开/etc/profile文件,在适当位置添加PATH=$PATH:/usr/local/mysql/bin,然后执行source/etc/profile使其生效 **

变量运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SeoEd0xe-1601295214237)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905162105101.png)]

r=$((2+5*8))
r=`expr 4 + 2`
r=$[1+2]
declare -i r=2+3
letr=3+4
echo "2+5*8" | bc
42
awk 'BEGIN {print2+5*8}'
42

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tj8Wb9v6-1601295214239)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905162341545.png)]

[root@localhost~]# str1="hello world"[root@localhost~]# echo ${#str1}
11

变量截取
指定起始位置,一直到结束[root@localhost~]#echo ${str1:1}
ello world
指定长度,不指定起始位置默认从开头开始
[root@localhost~]#echo ${str1::3}
hel
指定起始位置和长度
[root@localhost~]#echo ${str1:1:3}
ell从右边第几个字符开始,及字符的个数
[root@localhost~]#echo ${str1:0-1:1}
d
输出右边的几个字符
[root@localhost~]#echo ${str1: 0-5}
world
[root@localhost~]#echo ${str1: -5}
world注意:下面写法会输出全部,以${parameter:-default}方式,默认是提取完整地字符串
[root@localhost~]#echo ${str1:-5}
helloworld
删除字符串://获取后缀名tar.gz
[root@localhost~]#filename=testfile.tar.gz
[root@localhost~]#file=${filename#*.}
[root@localhost~]#echo$filetar.gz
//获取后缀名gz
[root@localhost~]#filename=testfile.tar.gz
[root@localhost~]#file=${filename##*.}
[root@localhost~]#echo $file
gz
//截取testfile.tar
[root@localhost~]#filename=testfile.tar.gz
[root@localhost~]#file=${filename%.*}
[root@localhost~]#echo $file
testfile.tar

//截取testfile
[root@localhost~]#filename=testfile.tar.gz
[root@localhost~]#file=${filename%%.*}
[root@localhost~]#echo $file
testfile

条件测试

在Shell程序中,用户可以使用测试语句来测试指定的条件表达式的条件的真或者假。当指定的条件为真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值。

格式1: test 条件表达式

格式2: [ 条件表达式 ]

格式3: [[ 条件表达式 ]]

注意:[]的左右要有空格。

文件测试表达式

[ 操作符 文件或目录 ]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SGOYQu0Q-1601295214240)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905165052826.png)]

//普通文件测试[root@localhost~]#touchfile1.txt
[root@localhost~]#[ -f file1.txt ] && echo yes || echo no 
yes
//目录测试
[root@localhost~]#[ -d /tm p] && echo yes || echo no
yes
//测试文件属性
[root@localhost~]#ll file1.txt-rw-r--r-- 1 root root 08月 28 12:30 file1.txt
[root@localhost~]#[ - rfile1.txt ] & echo yes || echo no
yes
[root@localhost~]#[ -x file1.txt ] & echo yes || echo no
no

字符串测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ncz1T7tP-1601295214241)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905165752042.png)]

#-n如果字符串长度不为零输出yes,否则输出no
[root@localhost~]#[ -n "hello" ] && echo yes || echo no
yes
[root@localhost~]#[ -n ""] && echo yes || echo no
no
#-z如果字符串长度为零输出yes,否则输出no
[root@localhost~]#[ -z "hello" ] && echo yes || echo no
no
[root@localhost~]#[ -z ""] && echo yes || echo no 
yes
//字符串相等比较注意:=的左右有空格,没有空格将会导致逻辑错误。
[root@localhost~]#[ "HELO" = "hello" ] && echo yes ||echo no
no
[root@localhost~]#[ "HELO" != "hello" ] && echo yes || echo no
yes

整数测试表达式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4iBD78H-1601295214241)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905170407611.png)]

[root@localhost~]#[ 5 -gt 3 ] && echo yes || echo no
yes
[root@localhost~]#[ `id-u` -eq 0  ] && echo admin || echo other 
admin
[root@localhost~]#su -student 
[ student@localhost~ ] $ [ `id-u` -eq 0 ] && echo admin || echo other
other

逻辑运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n0pX4KPG-1601295214242)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905170832757.png)]

[root@localhost~]#[ -f /etc/hosts -a -f /etc/services ] && echo yes || echo no
yes
[root@localhost~]#[[ -f /etc/hosts && -f /etc/services ]] && echo yes || echo no
yes

调试脚本

bash -x 

bash会先打印出每行脚本,再打印出每行脚本的执行结果,如果只想调试其中的几行脚本,可以用set-x和set+x把要调试的部分包含进来

set -x 
脚本部分内容
set +x

变量

内部变量:为了便于Shell编程而由Shell设定的变量。如错误类型的ERRNO变量。

本地变量:在代码块或函数中定义的变量,且仅在定义的范围内有效。

参数变量:调用Shell脚本或函数时传递的变量。

环境变量:为系统内核、系统命令和用户命令提供运行环境而设定的变量。

用户定义的变量:为运行用户程序或完成某种特定任务而设定的普通变量或临时变量。

变量的赋值

变量的赋值可以采用赋值运算符“=”实现

err=71
注意:中间不能有空格

内部变量

PWD:表示当前的工作目录,其变量值等同于pwd内部命令的输出。

RANDOM:每次引用这个变量时都会生成一个均匀分布的0~32767范围内的随机整数。

SCONDS:脚本已经运行的时间(单位:秒)。D PPID:当前进程的父进程的进程ID。

$?:表示最近一次执行的命令或shell脚本的出口状态。

自定义变量
定义变量:变量名=变量值 变量名必须以字母或下划线开头,区分大小写 ip1=192.168.2.115
引用变量:$变量名 或 ${变量名}
查看变量:echo $变量名 set(所有变量:包括自定义变量和环境变量)
取消变量:unset 变量名
作用范围:仅在当前shell中有效

环境变量

EDITOR:用于确定命令行编辑所用的编辑程序,通常为vim。

HOME :用户主目录。

PATH:指定命令的检索路径

定义环境变量:
方法一 export back_dir2=/home/backup
方法二 back_dir1=/home/backup

export back_dir1 将自定义变量转换成环境变量
引用环境变量:$变量名 或 ${变量名}
查看环境变量:echo $变量名 env 例如env |grep back_dir2
取消环境变量: unset 变量名
变量作用范围: 在当前shell和子shell有效

让环境变量的修改在退出shell再次登录时仍有效,需要在相关配置文件中修改。
Bash的初始化文件有:/etc/profile、/.bash_profile、/.bash_login、~/.profile、
~/.bashrc、/etc/bashrc

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zFHAA6Jz-1601295214243)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200815163150336.png)]

• /etc/profile 存放一些全局(共有)变量,不管哪个用户,登录时都会读取该文件。通常设置一些
Shell变量PATH,USER,HOSTNAME和HISTSIZE等
• ~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅
仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
• ~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该
文件被读取.
• /etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.

#上述配置文件中的作用
1)登录Linux先启动系统配置文件/etc/profile,并从/etc/profile.d目录的配置文件中搜集shell的
设置,为系统的每个用户设置环境信息。
2)用户配置文件~/.bash_profile,每个用户专用于自己使用的shell信息,仅用户登录时执行一次!
默认情况下,此文件通过脚本执行同目录下用户的.bashrc文件。
3)~/.bashrc文件包含专用于用户bash shell的bash信息,登录及每次打开新的shell时都会执行。里面
又会调用/etc/bashrc

#区别:bash_profile只在会话开始的时候读取一次,而bashrc则每次打开终端时都会读取
#配置的读取顺序
)配置文件的执行顺序
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->/etc/bashrc-->~./.bashrc
2)登录式shell的配置文件执行顺序
(清除所有变量,通过文件重新读入)
a.直接通过终端输入账号密码登录
b.使用“su - UserName”切换的用户
执行顺序:(影响该shell的配置文件)
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
3)非登录式shell配置文件执行顺序
(会继承上一个shell的全部变量):
a.su UserName
b.图形界面下打开终端
c.执行脚本(进入子shell)
d.任何其他的bash实例
执行顺序:(影响该shell的配置文件)
~/.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh

常用命令

print

print的功能与echo的功能完全一样,主要用于显示各种信息。在工作中主要用于跟awk配合,输出截取的字段详细信息

ps aux |  grep rsync-inotify.sh |grep - v  grep |   awk ’{print $2}’

read

read语句的主要功能是读取标准输入的数据,然后存储到变量参数中。如果read命令后面有多个变量参数,则输入的数据会按空格分隔单词顺序依次为每个变量赋值。

read -p 允许在read命令行中直接指定提示

read - p ”Enter your name: ” name 
注意:空格在变量name前面
read 变量名
read -p "提示信息: " 变量名
read -t 5 -p "提示信息: " 变量名
read -n 2 变量名

set和unset

set命令用于修改或重新设置位置参数的值。Shell规定,用户不能直接为位置参数赋值。使用不带参数的set将输出所有内部变量

该命令用于清除Shell变量,把变量的值设置为null。这个命令并不影响位置参数,比如我们先设置一个变量为a=34,然后用unset变量清除,如下所示:

unser a

expr

expr命令是一个手工命令行计数器,用于在Linux下求表达式变量的值,一般用于整数值,也可用于字符串。

用空格隔开每个项;

用/(反斜杠)放在shell特定的字符前面;

对于包含空格和其他特殊字符的字符串要用引号包含起来。expr命令支持的整数算术运算表达式如下:

expl+exp2,计算表达式expl和exp2的和。

expl-exp2,计算表达式expl和exp2的差。

expl/*exp2,计算表达式expl和exp2的乘积。

expl/exp2,计算表达式expl和exp2的商。

expl%exp2,计算表达式expl与exp2的余数。

expr命令还可支持字符串比较表达式,如下:

haha = hehe

这里为比较字符串strl和str2是否相等,如果计算结果真,同时输出1,则返回值为0。反之计算结果为假,则输出0,返回1。

let

let命令除了支持expr支持的五种算术运算外,还支持+=、-=、*=、/=、%=。

命令替换

命令替换的目的是获取命令的输出,且为变量赋值或对命令的输出做进一步的处理。命令替换实现的方法为采用$(...)形式引用命令或使用反向引号引用命令’command’。如

today=$(date)
echo $today
#文件filename中包含需要删除的文件列表时
rm $(cat filename)

test语句

test命令的主要功能是计算紧随其后的表达式、检查文件的属性、比较字符串或比较字符串内涵的整数值,然后以表达式的计算结果作为test命令的出口状态

文件属性测试表达式:

-e file,如果给定的文件存在,则条件测试的结果为真。,

-r file,如果给定的文件存在,且其访问权限是当前用户可读的,则条件测试的结果为真。

-w file,如果给定的文件存在,且其访问权限是当前用户可写的,则条件测试的结果为真。

-x file,如果给定的文件存在,且其访问权限是当前用户可执行的,则条件测试的结果为真。

-s file,如果给定的文件存在,且其大小大于0,则条件测试的结果为真。

-f file,如果给定的文件存在,且是一个普通文件,唰条件测试的结果为真。

-d file,如果给定的文件存在,且是一个目录,则条件测试的结果为真。

-L file,如果给定的文件存在,且是一个符号链接文件,则条件测试的结果为真。

-c file,如果给定的文件存在,且是字符特殊文件,则条件测试的结果为真。

-b file,如果给定的文件存在,且是块特殊文件,则条件测试的结果为真。

-p file,如果给定的文件存在,且是命名的管道文件,则条件测试的结果为真。

BACKDIR=/data/backup
[ -d ${ BACKDIR} ] I I mkdir -p ${BACKDIR} 
[ -d ${BACKDIR} I{DATE} ] || mkdir ${BACKDIR}/${DATE} [ ! -d ${BACKDIR} /  ${OLDDATE} ] 
|| rm -rf ${BACKDIR}/${0LDDATE}

下面是字符串测试运算符:0

-z str,如果给定的字符串长度为0,则条件的结果为真。

-nstr,如果给定的字符串长度大于0,则条件测试的结果为真。注意,要求字符串必须加引号

s1=s2,如果给定的字符串sl等同于字符串s2,则条件测试的结果为真。

s1!=s2,如果给定的字符串sl不等同于字符串s2,则条件测试的结果为真。

s1<s2,如果给定的字符串sl小于字符串s2,则条件测试的结果为真。例:if[ “ a ” < ” a”<” a<b” ]if[ ” a ” / < " a”/<" a<"b"],在单方括号的情况下,字符“〈”和“>”前需加转义符号。口sl>s2,若给定的字符串sl大于字符串s2,则条件测试的结果为真。在比较字符串的test语句中,变量或字符串表达式前后一定要加双引号。

数组

shell仅支持一维数组。类似与C语言,下标从0开始编号,获取数组中元素利用下标

定义数组

用括号来表示数组,数组元素用“空格”符号分割开

array_name=(value0 valuel value2 value3)
或者
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
#读取数组
valuen=${array_name(2]} 
使用@或*可以获取数组中的所有元素
${array name[*]} 
${array_name[@]]
获取数组的长度
length=${#array_name[@]}

字典

Shell也是支持字典的,不过要先进行声明,然后再定义,语法如下所示:

#必须先声明,然后再定义,这里定义了一个名为dic的字典declare -A dic 
dic= ( [keyl] = ”valuel” [key2]=”value2” [key3]=”value3”)

类似与python

Sed

Sed是Linux平台下的轻量级流编辑器一般用于处理文本文件。

它跟vim最大的区别是:它不需要像vim一样打开文件,可以直接在脚本里面操作文档,所以大家能发现它在Shell脚本里的使用频率是很高的。

Sed的基础语法格式

 sed [option] 'sed command' filename

其中:

-n:安静模式,只有经过sed处理过的行才显示出来,其他不显示。

-e:表示直接在命令行模式上进行sed操作。默认选项,不用写。

-f:将sed的操作写在一个文件里,使用-ffilename就可以按照内容进行sed操作了。

-r:表示使sed支持扩展正则表达式。

-i:直接修改读取的文件内容,而不是输出到终端。

n1,n2:选择要进行处理的行,如10,20表示在10~20行之间处理不一定需要。Sed格式中的动作支持如下参数:

a:表示添加,后接字符串,添加到当前行的下一行。

c:表示替换,后接字符串,用它替换nl到n2之间的行。

d:表示删除符合模式的行,它的语法为sed '/regexp/d',//之间是正则表达式,模式在d前面,d后面一般不接任何内容。

i:表示插入,后接字符串,添加到当前行的上一行。

p:表示打印,打印某个选择的数据,通常与-n(安静模式)一起使用。

s:表示搜索,还可以替换,类似与vim里的搜索替换功能。例如:1,20s/old/new/g表示替换1~20行的old为new,g在这里表示处理这一行所有匹配的内容。
1)#:#为数字,指定要进行处理操作的行
2)$:表示最后一行,多个文件进行操作的时候,为最后一个文件的最后一行
3)/regexp/:表示能够被regexp匹配到的行regexp及基于正则表达式的匹配
4)/regexp/I:匹配时忽略大小写
5)\%regexp%:任何能够被regexp匹配到的行,换用%(用其他字符也可以,如:#)为边界符号
6)addr1,addr2:指定范围内的所有的行(范围选定)
	常用地址定界表示方式:
	a)0,/regexp/:从起始行开始到第一次能够被regexp匹配到的行
	b)/regexp/,/regexp/:被模式匹配到的行内的所有的行
7)first~step:指定起始的位置及步长,例如:1~2表示1,3,5...
8)addr1,+N:指定行以及以后的N行addr1,~N:指定行开始的N行
将2~5行的内容替换成'I am a good man! ' : 
cat -n passwd |sed '2,5c I am a good man!'

正则表达式

在shell命令行中,用户可以使用grep命令来测试。grep家族有三大成员分别为:

grep:支持使用基本正则表达式。

egrep:支持使用扩展正则表达式。

fgrep:不支持使用正则表达式。

grep命令:

功能:根据用户指定的”pattern(过滤条件)“对目标文本逐行进行匹配检查;打印出符合条件的行,即文本搜索工具。

注:PATTERN即过滤条件指由文本字符及正则表达式元字符所编写的字符串。

grep
参数:
-n:显示行号
-o:只显示匹配的内容
-q:静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容
-l:如果匹配成功,则只将文件名打印出来,失败则不打印,通常-rl一起用,grep-rl'root'/etc
-A:如果匹配成功,则将匹配行及其后n行一起打印出来
-B:如果匹配成功,则将匹配行及其前n行一起打印出来
-C:如果匹配成功,则将匹配行及其前后n行一起打印出来
--color
-c:如果匹配成功,则将匹配到的行数打印出来
-E:等于egrep,扩展
-i:忽略大小写
-v:取反,不匹配
-w:匹配单词

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oN0bFd2r-1601295214244)(C:\Users\zhasutong\AppData\Roaming\Typora\typora-user-images\image-20200905174611042.png)]

1)^word表示搜索以word开头的内容。
2)word$表示搜索以word结尾的内容。
3)^$表示空行,不是空格。
4).代表且只能代表一个任意字符。
5)\转义字符,让有着特殊身份意义的字符。例如:\.只表示小数点,还原原始的小数点的意义。
6)*重复0个或多个前面的字符
7).*匹配所有的字符。^.*任意多个字符开头。
8)[]匹配字符集合内任意一个字符,如[a-z]
9)[^abc]^在中括号里表示非,不包含a或b或c
10){n,m}匹配n到m次,前一个字符。
{n,}至少N次,多了不限。
{n}N次
{,m}至多m次,少了不限。
注意:grep要{转义},\{\},egrep不需要转义
11)\<或\b:锚定词首(支持vi和grep),其后面的任意字符必须作为单词首部出现,如\<love或\blove
12)\>或\b:锚定词尾(支持vi和grep),其前面的任意字符必须作为单词尾部出现,如love\>或love\b
	后项引用:后面例子中会用到。
	分组:
		\(\)\(ab\)*
		后项引用
		\1:引用第一个左括号以及与之对应的右括号所包括的所有内容
		\2:
		\3:

awk

awk是一个强大的文本分析工具,相对于grep的查找以及sed的编辑,awk在对数据进行分析井生成报告时显得尤为强大

简单来说,awk就是把文件逐行的读人,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

内置变量

  FS        表示把行按照这个变量进行切割成列
   OFS      表示按这个字符把列进行拼装组合输出
   RS        表示按照这个变量作为行的分隔符
   ORS      表示以这个符号连接每行输出的结果
   NF         表示字段的数量大小
   NR         表示行号
   FNR       多个文件的时候各自的文件行号
   FILENAME       表示当前的文件名称

awk程序执行方式

1.通过命令行执行awk程序,语法如下:awk 'program-text' datafile
2.执行awk脚本在awk程序语句比较多的情况下,用户可以将所有的语句写在一个脚本文件中,然后通过awk命令来解释并执行其中的语句。awk调用脚本的语法如下:awk -f program-file file ..
在上面的语法中,-f选项表示从脚本文件中读取awk程序语句,program-file表示awk脚本文件名称,
file表示要处理的数据文件。
3.可执行脚本文件在上面介绍的两种方式中,用户都需要输入awk命令才能执行程序。除此之外,用户还可以通过类似于Shell脚本的方式来执行awk程序。在这种方式中,需要在awk程序中指定命令解释器,并且赋予脚本文件的可执行权限。其中指定命令解释器的语法如下:#!/bin/awk -f以上语句必须位于脚本文件的第一行。然后用户就可以通过以下命令执行awk程序:
awk-script file
其中,awk-script为awk脚本文件名称,file为要处理的文本数据文件

语法

awk 'pattern {action}' filename 
awk [options] 'script' file1 file2, ...
awk [options] 'PATTERN { action }' file1 file2, ...

pattern就是要表示的正则表达式,它表示awk在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行后,就会执行相应的命令来处理文本

awk程序由三部分组成,分别为:

  • 初始化:处理输入前做的准备,放在BEGIN块中。
  • 数据处理:处理输入数据。
  • 收尾处理:处理输入完成后要进行的处理,放到END块中。

在“数据处理”过程中,指令被写成一系列模式/动作过程,模式是用于测试输入行的规则,以此确定是否将应用于这些输入行

awk调用方式

**1.**命令行方式

awk [-F field-separator] ’commands ’ filename

commands是真正的awk命令,[-F 域分隔符]是可选的,filename是待处理的文件

在awk文件的各行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

**2.**使用-f选项调用awk程序

awk允许将一段awk程序写入一个文本文件,然后在awk命令行中用,f选项调用并执行这段程序

awk -f wak-script-file filename

-f 选项加载awk-script-file中的awk脚本,filename表示文件名

**3.**利用命令解释器调用awk程序

利用Linux系统支持的命令解释器功能可以将一段awk程序写入文本文件,然后在它的第一行加上如下代码:

awk语法

awk [ -F re] [parameter...] [’prog'] [-f progfile] [in_file ... ]

-F re:允许awk更改其字段分隔符。

parameter:该参数帮助为不同的变量赋值。

prog:awk的程序语句段。这个语句段必须用单引号‘和’括起,以防被shell解释。

-f progfile:允许awk调用并执行progfile指定的程序文件。progfile是一个文本文件,它必须符合awk的语法。

in_file : awk的输入文件,awk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。

awk中的print和printf

awk中同时提供了print和printf两种打印输出的函数。

print函数的参数可以是变量、数值或字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起,无法区分。这里,逗号的作用与输出文件的分隔符作用是一样的,只是后者是空格而已。

printf函数,其用法和C语言中printf基本相似,可以格式化字符串,输出复杂时,printf的结果更加人性化。

awk变量

1)awk内置变量之记录变量
FS:fieldseparator,读取文件本时,所使用字段分隔符;OFS:OutputFiledSeparator:输出分割符
awk -F: F指定输入分割符OFS=#”指定输出分割符示例:
[root@localhost~]#echo "thisis" > test.txt
[root@localhost~]#awk 'BEGIN {OFS="#"} {print $1,$2,"a","test"}' test.txt
this#is#a#test
2)awk内置变量之数据变量
NR:Thenumberofinputrecords,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
NF:NumberofField,当前记录的field个数;当前行的字段总数FNR:与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;awk可能处理多个文件,各自文件计数
ENVIRON:当前shell环境变量及其值的关联数组;
示例:[root@localhost~]#awk 'BEGIN {print ENVIRON["PATH"]}'
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
3)用户自定义变量gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。gawk变量名称区分字符大小写。
A、在gawk中给变量赋值使用赋值语句进行
示例:[root@localhost~]#awk 'BEGIN {test="hello";printtest}' hello
B、在命令行中使用赋值变量
gawk命令也可以在“脚本”外为变量赋值,并在脚本中进行引用。例如,上述的例子还可以改写为:
[root@localhost~]#awk -v test="hello" 'BEGIN {print test}'
hello

awk操作符

1)算术操作符
-x:负值
+x:转换为数值
x^y:次方
x**y:次方
x*y:
x/y:
x+y:
x-y:
x%y:
示例:[root@localhost~]#awk 'BEGIN {x=2;y=3;print x**y,x^y,x*y,x/y,x+y,x-y,x%y}'
8860.6666675-12
2)字符串操作符只有一个,而且不用写出来,用于实现字符串拼接;示例:[root@localhost~]#awk ' BEGIN {print "This","is","test"}
Thisistest
3)
赋值操作符
=
+=
-=
*=
/=
%=
^=
**=
++
--
需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;
示例:[root@localhost~]#awk 'BEGIN {x=2;y=x;printf "%-5s%i\n%-5s%i\n","++x=",++x,"--y=",--y}'
++x= 3
--y= 1
4)布尔值
awk中,任何非0值或非空字符串都为真,反之就为假;
5)比较操作符
x<y  True if x is less than y.
x<=y True if x is less than or equal to y.
x>y  True if x is greater thany.
x>=y True if x is greater than or equal to y.
x==y True if x is equal to y.
x!=y True if x is not equal to y.
x~y  True if the string x matches the regexp denoted by y.
x!~y True if the string x doesnot match the regexp denoted by y.
示例:
6)逻辑关系符&&||
7)条件表达式
selector?if-true-exp:if-false-exp
if selector;then
if-true-exp
else
if-false-exp
fi
a=3
b=4
a>b?
a is max:b ia max
#cat num
5  8
7  2
1  9
6  4
7  2
使用条件测试表达式打印出每行的最大值:
#awk '{max=$1>$2?$1:$2;print NR,"max=",max}' num
1 max = 8
2 max = 7
3 max = 9
4 max = 6
5 max = 7

Shell多进程并发

如果逻辑控制在时间上重叠,那么它们就是并发的(concurrent),这种常见的现象称为并发(concurrency),出现在计算机系统的许多不同层面上。

1)进程。用这种方法,每个逻辑控制流都是一个进程,由内核来调度和维护。因为进程有独立的虚拟地址空间,想要和其他流通信,控制流必须使用进程间通信(IPC)。

  1. I/O多路复用。这种形式的并发,应用程序在一个进程的上下文中显示调度自己的逻辑流。逻辑流被模拟为“状态机”,数据到达文件描述符后,主程序显示地从一个状态转换到另一个状态。因为程序是一个单独的进程,所以所有的流都共享一个地址空间。

3)线程。线程是运行在一个单一进程上下文中的逻辑流,由内核进行调度。线程可以看做是进程和I/O多路复用的合体,像进程一样由内核调度,像I/O多路复用一样共享一个虚拟地址空间。

shell脚本执行方式

运行Shell脚本时,有以下两种方式可调用外部的脚本,即exec方式和source方式。

  1. exec方式:使用exec调用脚本,被执行的脚本会继承当前shell的环境变量。但事实上exec产生了新的进程,它会把主Shell的进程资源占用并替换脚本内容,继承原主Shell的PID号,即原主Shell剩下的内容不会执行。

  2. source方式:使用source或者“.”调用外部脚本,不会产生新的进程,继承当前Shell环境变量,而且被调用的脚本运行结束后,它拥有的环境变量和声明变量会被当前Shell保留,类似将调用脚本的内容复制过来直接执行。执行完毕后原主Shell继续垣行。

  3. fork方式:直接运行脚本,会以当前shell为父进程,产生新的进程,并继承主脚本的环境变量和声明变量。执行完毕后,主脚本不会保留其环境变量和声明变量。

工作中推荐使用source方式来调用外部的Shell脚本,稳定性高,不会出一些诡异的问题和bug,影响主程序的业务逻辑(大家也可以参考下Linux系统中的Shell脚本,如/etc/init.d/network等,基本上都是采用这种处理方式)。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值