shell函数和三剑客
函数
基本语法
# 写法一: function 函数名(){ 函数要执行的命令 } # 写法二,省略(): function 函数名 { 函数要执行的命令 } # 写法三,省略function: 函数名 () { 函数要执行的命令 } # 调用函数 # 没有参数的函数 函数名 # 有参数的函数 函数名 参数一 参数二
函数的返回值
# return 返回1-255的整数,0表示正确执行,其他数字表示没有正确执行 [root@head test]# cat test.sh #!/usr/bin/bash export aaa=123 function test() { a=123 echo $a return 0 } test # echo 返回字符串,可定义变量接收函数的返回值 [root@head test]# cat test.sh #!/usr/bin/bash export aaa=123 function test() { a=123 echo $a } bbb=`test` echo $bbb
代码示例
# 代码示例一: [root@head test]# cat test.sh #!/usr/bin/bash function test() { echo $# echo $@ echo $* echo $1 echo $? } test 1 2 3 4 5 6 # 代码示例二: # 函数内的return的结果是指函数的状态,0代表成功,其他代表失败 # 示例二中执行完脚本后,用$?获取状态为1 [root@head test]# cat test.sh #!/usr/bin/bash function test() { echo 111 return 1 } # 代码示例三: # local的使用,用local定义局部变量。shell中定义的变量,默认都是全局变量,此示例中如果不用local,则第二个$a也是有值的 [root@head test]# cat test.sh #!/usr/bin/bash function test() { local a=123 echo $a } test echo $a # 值为空 test # 说明:如果在当前进程中引用了脚本,则脚本中的变量也会生效 [root@head test]# bash test.sh 123 123 [root@head test]# [root@head test]# echo $a [root@head test]# source test.sh 123 123 [root@head test]# echo $a 123
grep
在文件中查找内容的状态
# 正常查找 [root@head ~]# grep "root" /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@head ~]# echo $? 0 # 查找不到内容 [root@head ~]# grep "aaaaaaa" /etc/passwd [root@head ~]# echo $? 1 # 后面跟的文件不存在 [root@head ~]# grep "root" /etc/password grep: /etc/password: No such file or directory [root@head ~]# echo $? 2
grep参数详解
# -n --line-number 显示查找到的内容在文件中的行号 [root@head ~]# grep -n "root" /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 10:operator:x:11:0:operator:/root:/sbin/nologin # -o --only-matching 只显示需要匹配的内容 [root@head ~]# grep -o "root" /etc/passwd root root root root # -q --quiet 静默输出,可用$?获取匹配是否成功 [root@head ~]# grep -q "root" /etc/passwd [root@head ~]# echo $? 0 # -i --ignore-case 忽略大小写 [root@head test]# grep -i "a" ./ccc01.txt aaa AAA # -A --after-context=NUM 如果匹配成功,则将其后面N行也打印出来 [root@head ~]# grep -A 2 "mysql" /etc/passwd mysql:x:27:27:MySQL Server:/var/lib/mysql:/sbin/nologin influxdb:x:299:299:user for InfluxDB database server:/var/lib/influxdb:/sbin/nologin ldap:x:55:55:OpenLDAP server:/var/lib/ldap:/sbin/nologin # -B --before-context=NUM 如果匹配成功,则将其前面N行也打印出来 [root@head ~]# grep -B 2 "mysql" /etc/passwd epmd:x:987:981:Erlang Port Mapper Daemon:/dev/null:/sbin/nologin rabbitmq:x:984:980:RabbitMQ messaging server:/var/lib/rabbitmq:/sbin/nologin mysql:x:27:27:MySQL Server:/var/lib/mysql:/sbin/nologin # -C --context=NUM 如果匹配成功,则将其上写N行也打印出来 [root@head ~]# grep -C 1 "mysql" /etc/passwd rabbitmq:x:984:980:RabbitMQ messaging server:/var/lib/rabbitmq:/sbin/nologin mysql:x:27:27:MySQL Server:/var/lib/mysql:/sbin/nologin influxdb:x:299:299:user for InfluxDB database server:/var/lib/influxdb:/sbin/nologin #-c --count 如果匹配成功,将匹配成功的行数打印出来 [root@head ~]# grep -c "root" /etc/passwd 2 # -v --invert-match 取反,将不匹配的行打印出来 [root@head test]# grep -i -v "a" ./ccc01.txt vvv -r --recursive 递归匹配 # -l --files-with-matches 如果文件内容有匹配成功的,则将文件名打印出来 [root@head test]# grep -rl "a" /home/test # -w 匹配整个单词 [root@head test]# grep -w "test" ./ccc01.txt test
[root@head test]# netstat -nltp | grep -w 80
tcp6 0 0 :::80 :::* LISTEN 1132/httpd
# -E 相当于egrep扩展
grep正则匹配示例
# ^ 匹配开头 [root@head test]# grep ^root /etc/passwd root:x:0:0:root:/root:/bin/bash # $ 匹配结尾 [root@head test]# grep "shutdown$" /etc/passwd shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown # . 匹配任意一个字符 [root@head test]# grep "a." ./ccc01.txt atest atesta # * 匹配0个或多个字符 [root@head test]# grep "a*" ./ccc01.txt atest test atest # .* 匹配所有字符 [root@head test]# grep "a.*" ./ccc01.txt atest atesta # [] 匹配字符组内的任意字符 [root@head test]# grep [at] ./ccc01.txt atest test atesta # [^] 取反,不匹配字符组内的所有字符 [root@head test]# grep [^at] ./ccc01.txt atest test atesta
sed
sed选项
# -e 允许多项编辑 [root@head test]# cat ccc01.txt atest test atesta [root@head test]# [root@head test]# sed -e '1d' -e '3d' ccc01.txt test # -n 取消模式空间的内容输出 [root@head test]# sed -n -e '1d' -e '3d' ccc01.txt [root@head test]# # -i 将修改内容保存到文件中 [root@head test]# sed -i -e '1d' -e '3d' ccc01.txt [root@head test]# cat ccc01.txt test # -f 指定sed脚本的文件名
# -r 支持扩展元字符
sed常用命令
# a 追加命令,前面指定在文件的第N行追加 [root@head test]# sed "2a111" ccc01.txt atest test 111 atesta # c 修改命令,用当前文本修改文件中的第N行 [root@head test]# sed "2c111" ccc01.txt atest 111 atesta # d 删除命令,删除文件中的第N行 [root@head test]# sed "2d" ccc01.txt [root@head test]# sed "/atest/d" ccc01.txt test # i 插入命令 [root@head test]# sed "2i111" aa.txt atest 111 test atesta # s 替换命令,替换文件中的内容 [root@head test]# sed "s/test/real/" aa.txt areal real areala
awk
awk基本语法
# 语法格式,注意awk后面的命令是单引号,如果是双引号的话里面带$符的会被识别成变量,有时会出现问题 awk [options] 'commands' filename # options选项: -F # 定义字段分隔符,默认的是以空格或者是制表符分隔 # commands分为三部分 BEGIN{} # 读所有行之前做的事情,只执行一次,可以省略 {} # 读所有行的时候做的事情 END{} # 读完所有行之后做的事情,只执行一次,可以省略
awk字段相关的内部变量
$0 # 记录的读取文件当前行的内容 awk '{print $0}' aa.txt # 将此文件的所有内容都读出来了 NR # 记录号,每处理完一条记录,记录号加1 awk '{print NR}' aa.txt NF # 保存记录的字段数,$1,$2...$100 wk '{print NF}' aa.txt # 如果有分隔符,则会根据分隔符分隔后再计算每一行有多少个字段 FS # 就是-F,输入字段分隔符,默认空格 awk -F t '{print $0,NF}' aa.txt OFS # 输入字段分隔符,默认空格 awk -F : 'BEGIN{OFS="-"}{print$1,$3}' /etc/passwd # $1和$3字段会用"-"连接起来,默认是空格