Shell语法
~: 家目录 cd - 代表切到上一级目录
!: 执行历史命令!$NUM !!执行上一次命令
$: 变量
+ - * / %: 加 减 乘 除 取余
&: 后台执行
*: 匹配所有
?: 匹配除回车以外的一个字符
;: 执行多个命令 之间用;分割
|; 管道符 上一个命令的输出作为下一个命令的输入
\; 转义字符
echo $?: 判断上一条命令是否执行成功,0成功1否
` `:反引号,命令中执行命令 echo "date is `date`"
'':单引号与双引号一样,但是单引号不解释变量
Shell 重定向
<: 重定向输出 wc -l < file
>: 重定向输入 覆盖原有数据 echo "123" > file
<<: 重定向追加输出 fdisk /dev/sda <<EOF ...... EOF
>>: 重定向追加输入 在原有末尾追加 echo "123" >> file
Shell数学运算
expr: 只能做整数运算 格式古板
expr 1 + 2
expr 1 - 2
expr 1 \* 2
expr 10 / 2
expr 11 % 2 取余
bc:
echo "`echo "scale=3;332/2827*100" | bc`%"
Shell中(())也可以用来运算
echo
输出内容
-n:不自动换行
-e: 转义符不按字符串输出
#!/bin/bash
echo -e "\t\t\t\t Frutis"
echo -e "\t(1 Apple"
echo -e "\t(2 Banana"
[root@K8S-Node2 ~]# bash echo.sh
Frutis
(1 Apple
(2 Banana
数组
ARRAY1=('a' 'b' 'c' 'd')
echo ${ARRAY1[1]} #echo {$数组名[索引]} 获取索引为1的元素
echo ${数组名[@]} #数组中所有元素
echo ${#数组名[@]} #统计数组元素个数
echo ${!数组名[@]} #获取元素索引
echo ${数组名[@]:1} #从索引1开始读取元素
echo ${数组名[@]:1:5} #从索引1开始 获取5个元素
declare -a #可以查看系统中的数组
关联数组
声明关联数组
declare -A 数组名
数组名[key]=value
数组名=([key]=value)
declare -A people
declare -A people1
people=([name]='dzy' [age]=21 [taller]=180)
echo ${people[name]}
echo ${people[age]}
echo ${people[taller]}
people1[name]='cff'
people1[age]=20
echo ${people1[name]}
数学比较运算
运算符解释
-eq 等于
-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于
-ne 不等于
NUM1=`echo "1.5*10"|bc|cut -d "." -f1`
NUM2=$((10*2))
test $NUM1 -eq $NUM2;echo $?
字符串比较运算
运算符 | 说明 | 距离 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ b ] 返回 true。 |
-Z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n "$a" ] 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
test $USER=="root" ;echo $?
test -z "$USER";echo $?
test -n "$USER";echo $?
文件比较与检查(test命令)
-b<文件>:如果文件为一个块特殊文件,则为真;
-c<文件>:如果文件为一个字符特殊文件,则为真;
-d<文件>:如果文件存在且为目录则为真;
-e<文件>:如果文件存在,则为真;
-f<文件>:如果文件为一个普通文件,则为真;
-g<文件>:如果设置了文件的SGID位,则为真;
-G<文件>:如果文件存在且归该组所有,则为真;
-k<文件>:如果设置了文件的粘着位,则为真;
-O<文件>:如果文件存在并且归该用户所有,则为真;
-p<文件>:如果文件为一个命名管道,则为真;
-r<文件>:如果文件可读,则为真;
-s<文件>:如果文件的长度不为零,则为真;
-S<文件>:如果文件为一个套接字特殊文件,则为真;
-u<文件>:如果设置了文件的SUID位,则为真;
-w<文件>:如果文件可写,则为真;
-x<文件>:如果文件可执行,则为真。
逻辑运算
逻辑与运算 && 真真为真 真假为假 假假为假
逻辑或运算 || 真真为真 真假为真 假假为假
逻辑非运算 ! 非真既假 非假既真 (即取相反)
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if语法
if [ condition ] #判断condition(条件),指的是Shell中的五中运算
then
commands
fi
if (()) #双小括号可做数学运算
then
command
fi
if
if [[]] #双中括号可做字符串匹配
then
command
fi
if [ ! -d /tmp/abc ]
then
mkdir -p /tmp/abc
echo "123"
echo "create /tmp/abc ok"
fi
if then else语句
if [ condition ]
then
command
else
command
fi
if [ ! -d /tmp/abc ]
then
mkdir -p /tmp/abc
echo "123"
echo "create /tmp/abc ok"
else
echo "i am your father"
fi
if嵌套
if [ condition ]
then
command
else
if [condition ]
then
command
else
command
fi
if [ $1 -eq $2 ]
then
echo "$1=$2"
else
if [ $1 -gt $2 ]
then
echo "$1 > $2"
else
echo "$1 < $2"
fi
fi
多部判断
if [ condition ]
then
command
elif [ condition ]
then
command
elif [ condition ]
then
command
else
command
fi
nginx自动安装脚本实例
#!/bin/bash
wget http://nginx.org/download/nginx-1.6.2.tar.gz
if [ $? -eq 0 ]
then
tar -zxvf nginx-1.6.2.tar.gz;
cd nginx-1.6.2;
./configure --prefix=/usr/local/nginx
if [ $? -eq 0 ]
then
make
if [ $? -eq 0 ]
then
make install
else
echo "安装失败"
fi
else
echo "编译失败"
fi
else
echo "下载失败"
fi
For语句介绍
for var in var1 var2 .....
do
command
done
例如
for var in `seq 1 9`
do
echo $var
done
#C格式语法
for (( i=0;i<10;i++ )) # i=0 条件为 i<10,i++ 每次i+1
do
echo $i
done
#多变量C格式语法
for (( i=10,m=0;i>0,m<10,i--,m++ )) #i=10 条件为 i>0 即循环制i=0
do
echo -e "$i\t$m"
done
循环控制
sleep N 脚本执行到该步休眠N秒
for i in `seq 9 -1 1`
do
echo -n -e "\b$i"
sleep 1
done
echo
for ((;;)) #无限循环
do
ping -c1 $1 &>/dev/null #ping -c1 ping一次 结果输出到/dev/null
if [ $? -eq 0 ]
then
echo "`date +"%F %H:%M:%S"`: $1 is UP"
else
echo "`date +"%F %H:%M:%S"`: $1 is DOWN"
fi
sleep 5
done
continue 跳过本次循环,继续执行循环以及以下代码
for ((i=1;i<10;i++))
do
if [ $i -eq 5 ]
then
continue
else
echo $i
fi
done
break 跳出循环继续执行后续代码
for i in `seq 1 1 9`
do
if [ $i -eq 9 ]
then
break
else
echo $i
fi
done
多层循环嵌套
for ((i=1;-<100;i++))
do
echo "#loop $i"
for ((;;))
do
echo "haha" #内层嵌套for循环 如果不跳出内层for循环 则外层循环将不会进行第二次循环,内存循环将进入死循环
break 2 #2的意思是 从内到外的循环嵌套成熟 从内到外 1 2
done
sleep 3
done
While循环语句
while [ condition ] #条件成立循环,条件不成立停止循环
do
commands
done
read -p "请输入数字: " NUM1
while [ $NUM1 -gt 0 ]
do
echo "大于"
sleep 3
done
while的嵌套if for while
打印 1-10 当 i = 5 时停止
i=1
while [ $i -lt 10 ]
do
i=$((i+1))
echo $i
if [ $i -eq 5 ];then
break #跳过5 break换成continue
fi #相当于Python中的计数器
done
while与for打印99乘法表
i=1
while [ $i -lt 10 ]
do
for ((m=1;m<=$i;m++));do
echo -n -e "$i * $m = $((i*m))\t"
done
echo #此echo代表换行
i=$((i+1))
done
while嵌套while打印99乘法表
i=1
while [ $i -lt 10 ];do
m=1
while [ $m -le $i ];do
echo -n -e "$i * $m = $((i*m))\t"
m=$((m+1))
done
echo #此echo代表换行
i=$((i+1))
done
Case语句
根据不同的条件执行不同的代码块
case 变量 in
条件1)
代码块
;;
条件2)
代码块
;;
esac
read -p "NUM: " i
case $i in
1)
echo "hehe"
;;
2)
echo "heihei"
;;
*)
echo "1|2"
;;
esac
Shell特殊变量
$@: 与*类同,不同之处在于不参照IFS
$#: 代表传递参数数量
$?: 执行上一个指令的返回值
$-: 最近执行的 foreground pipeline的选项参数
$$: 本身的PID
$: 执行上一个背景指令的PID
$_: 最后执行的命令
$N: Shell的第N个外传采纳数
函数
函数名() {
代码块
return
}
function 函数名{
代码块
return
}
Nginx启动脚本示例
#variables
nginx_install_doc=/usr/local/nginx
nginxd=$nginx_install_doc/sbin/nginx
pid_file=$nginx_install_doc/logs/nginx.pid
# Source funciton libary
if [ -f /etc/init.d/functions ];then
. /etc/init.d/functions
else
echo "error"
exit
fi
if [ -f $pid_file ];then
nginx_process_id=`cat $pid_file`
nginx_process_num=`ps -aux | grep $nginx_process_id | grep -v "grep" | wc -l`
fi
#function
function start {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ];then
echo "nginx running"
else
if [ -f $pid_file ] && [ $nginx_process_num -lt 1 ];then
rm -f $pid_file
daemon $nginxd
fi
daemon $nginxd
fi
}
function stop {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ];then
action "nginx stop" killall -s QUIT $nginxd
rm -rf $pid_file
else
action "nginx stop fail" killall -s QUIT $nginxd 2>/dev/null
fi
}
function restart {
stop
sleep 3
start
}
function reload {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ];then
action "nginx reload" stop
sleep 3
action "nginx reload complete" start
fi
}
function status {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ];then
echo "Nginx running....."
else
echo "Nginx stop......"
fi
}
case $1 in
start) start;;
stop) stop;;
restart) restart;;
status) status;;
reload)reload;;
*)echo "Usage: $0 start|stop|restart|reload|status";;
esac
正则表达式
正则表达式是一种文本模式匹配.包含普通字符和特殊字符.可以哟用来检查一个字符串包含某种子串。将匹配的子串替换或者从字符串中取出
在shell中 只有 grep awk sed 支持正则表达式
特殊字符
定位符 | 说明 |
---|---|
^ | 锚定开头 ^a 以a开头 默认锚定一个字符 |
$ | 锚定结尾 a$ 以a结尾 默认锚定一个字符 |
默认的grep不支持正则表达式 需要加 -E grep -E 等于 egrep
匹配符 | 说明 |
---|---|
. | 匹配除回车意外的任意字符 |
[] | 字符类,匹配括号中的一个字符 |
[^] | 表示取括号中字符类的相反值 |
() | 字符串分组 |
\ | 转义字符 |
[root@K8S-Node3 ~]# egrep "^ac$" file
ac
.代表任意字符.表示以a开头以c结尾中间任意字符的字符串
[root@K8S-Node3 ~]# egrep "^a.c$" file
asc
a2c
awc
aec
atc
[]与.的意思一样.但是可以在[]中定义字符或者数字区间
[root@K8S-Node3 ~]# egrep "^a[0-9]c$" file
a2c
a2c
a3c
a4c
a5c
a6c
a7c
[root@K8S-Node3 ~]# egrep "^a[a-z]c$" file
asc
awc
aec
atc
[root@K8S-Node3 ~]# egrep "^a[^a-z]c$" file
a2c
a2c
a3c
a4c
a5c
a6c
a7c
[root@K8S-Node3 ~]# egrep "^a[^0-9]c$" file
asc
awc
aec
atc #在[]中加上^代表取相反的值
[root@K8S-Node3 ~]# egrep "^a*c$" file
ac
[root@K8S-Node3 ~]# egrep "^a\*c$" file
a*c
[root@K8S-Node3 ~]# egrep "^(a|b)c$" file #^(a|b) 表示以a或b开头的字符串
ac
ac
bc
[root@K8S-Node3 ~]#
限定符
限定符 | 说明 |
---|---|
* | 某个字符之后加*表示该字符出现多次或不出现 |
? | 某个字符之后加?表示该字符不出现或只出现一次 |
+ | 某个字符之后加+ 表示该字符出现一次或多次,但必须出现一次 |
{m,n} | 某个字符之后加{n,m} n表示最少出现多少次,最多m次 |
{m} | 正好出现m次 |
[root@K8S-Node3 ~]# egrep "^ba*c$" file
bc
baaaaaaaaaac
bac
[root@K8S-Node3 ~]#
[root@K8S-Node3 ~]# egrep "^ba?c$" file
bc
bac
[root@K8S-Node3 ~]#
[root@K8S-Node3 ~]# egrep "^ba+c$" file
baaaaaaaaaac
bac
[root@K8S-Node3 ~]#
[root@K8S-Node3 ~]# egrep "^ab{3}c$" file
abbbc
[root@K8S-Node3 ~]# egrep "^ab{3,7}c$" file
abbbbc
abbbc
abbbbbbbc
[root@K8S-Node3 ~]#
POSIX特殊字符
特殊字符 | 说明 |
---|---|
[:alnum:] | 匹配任意字母字符0-9 a-z A-Z |
[:alpha:] | 匹配任意字母,大写或小写 |
[:dight:] | 数字0-9 |
[:graph:] | 非空字符(不包括空格) |
[:lower:] | 小写字母a-z |
[:upper:] | 大写字母A-Z |
[:cntrl:] | 控制字符 |
[:print:] | 非空字符(包括空格) |
[:punct:] | 标点符号 |
[:blank:] | 空格和TAB字符 |
[:xdigit:] | 16进制数字 |
[:space:] | 所有空白字符(新行,空格,制表符) |
[root@K8S-Node3 ~]# egrep "^http[[:punct:]]{2}[[:punct:]]{2}[[:punct:]]{2}192.168.129.130.com$" file
http::**//192.168.129.130.com
[root@K8S-Node3 ~]# egrep "^[[:alpha:]]*.[1-6]{3}.com$" file
youngzheyuan@163.com
[root@K8S-Node3 ~]#
Shell对文件的操作
sed命令
语法:
sed [options]'{command}{flags}' [filename]
命令选项
-e script 将脚本中指定的命令添加到处理输入时执行的命令中 一行要有多个条件
-f script 将文件中指定的命令添加到处理输入时执行的命令中
-n 抑制自动输出
-i 编辑文件内容
-i.bak 修改时同时创建 bak备份文件
-r 使用正则表达式
! 取反
sed常用命令
a 在匹配行后面添加
i 在匹配行前面添加
p 打印
d 删除行
s 查找替换字符
c 更改行
y 转换 N D P
flags
数字 表示新文本替换的模式
g: 表示用新文件替换现有文本的全部实例
p: 表示打印原始内容
w filename: 将替换的结果写入文件
sed常用命令
a 在匹配行后面添加
i 在匹配行前面添加
p 打印
d 删除行
s 查找替换字符
c 更改行
y 转换 N D P
[root@K8S-Node3 ~]# sed 'a\hello world' date
1 abc
hello world
2 abc
hello world
3 abc
hello world
4 abc
hello world
5 abc
hello world
[root@K8S-Node3 ~]# sed '3a\hello world' date
1 abc
2 abc
3 abc
hello world
4 abc
5 abc
[root@K8S-Node3 ~]# sed '3i\hello world' date
1 abc
2 abc
hello world
3 abc
4 abc
5 abc
[root@K8S-Node3 ~]# sed '3,5i\hello world' date
1 abc
2 abc
hello world
3 abc
hello world
4 abc
hello world
5 abc
[root@K8S-Node3 ~]#
[root@K8S-Node3 ~]# sed '/3 abc/a\hello world' date
1 abc
2 abc
3 abc
hello world
4 abc
5 abc
[root@K8S-Node3 ~]# #//代表匹配模式 此条命令表示匹配 3 abc 在此行下添加 hello world
[root@K8S-Node3 ~]# sed -r '/(^#|#|^$)/d' nginx.conf #删除以#开头或包含#或空行
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@K8S-Node3 ~]# sed '/3 abc/d date' #删除 3 abc这行
[root@K8S-Node3 ~]# sed '3s/abc/cat/' date 更改第三行的abc为cat
1 abc
2 abc
3 cat
4 abc
5 abc
[root@K8S-Node3 ~]# sed 's/abc/cat/' date
1 cat
2 cat
3 cat
4 cat
5 cat
[root@K8S-Node3 ~]# sed '/3 abc/s/abc/cat/' date #匹配3 abc 更改 abc 为 cat
1 abc
2 abc
3 cat
4 abc
5 abc
[root@K8S-Node3 ~]#
[root@K8S-Node3 ~]# sed 'c\hello world' date
hello world
hello world
hello world
hello world
hello world
[root@K8S-Node3 ~]# sed '/3 abc/c\hello world' date
1 abc
2 abc
hello world
4 abc
5 abc
[root@K8S-Node3 ~]#
[root@K8S-Node3 ~]# sed 'y/abc/DZY/' date #与s类似
1 DZY
2 DZY
3 DZY
4 DZY
5 DZY
[root@K8S-Node3 ~]#
flags
数字 表示新文本替换的模式
g: 表示用新文件替换现有文本的全部实例
p: 表示打印原始内容
w filename: 将替换的结果写入文件
[root@K8S-Node3 ~]# sed 's/abc/dog/' date #替换第一处
1 dog.abc
2 dog.abc
3 dog.abc
4 dog.abc
5 dog.abc
[root@K8S-Node3 ~]# sed 's/abc/dog/g' date #全部替换
1 dog.dog
2 dog.dog
3 dog.dog
4 dog.dog
5 dog.dog
[root@K8S-Node3 ~]# sed 's/abc/dog/2' date #替换指定处
1 abc.dog
2 abc.dog
3 abc.dog
4 abc.dog
5 abc.dog
命令选项
-e script 将脚本中指定的命令添加到处理输入时执行的命令中 一行要有多个条件(修改多处,用;分隔)
-f script 将文件中指定的命令添加到处理输入时执行的命令中
-n 抑制自动输出
-i 编辑文件内容
-i.bak 修改时同时创建 bak备份文件
-r 使用正则表达式
! 取反
默认不加参数的情况下,sed是修改内存中文件内容,并不直接修改文本内容
[root@K8S-Node3 ~]# sed 's/abc/dog/p' date #-n
1 dog.abc
1 dog.abc
2 dog.abc
2 dog.abc
3 dog.abc
3 dog.abc
4 dog.abc
4 dog.abc
5 dog.abc
5 dog.abc
[root@K8S-Node3 ~]# sed -n 's/abc/dog/p' date
1 dog.abc
2 dog.abc
3 dog.abc
4 dog.abc
5 dog.abc
[root@K8S-Node3 ~]#
-e script 将脚本中指定的命令添加到处理输入时执行的命令中 一行要有多个条件(修改多处,用;分隔)
[root@K8S-Node3 ~]# sed -e 's/abc/dog/;s/efg/cat/' date
1 dog.abc.cat
2 dog.abc.cat
3 dog.abc.cat
4 dog.abc.cat
5 dog.abc.cat
-f script 将文件中指定的命令添加到处理输入时执行的命令中(指定sed命令行文件)
[root@K8S-Node3 ~]# cat xx
s/abc/dog/g
s/efg/cat/
[root@K8S-Node3 ~]# sed -f xx date
1 dog.dog.cat
2 dog.dog.cat
3 dog.dog.cat
4 dog.dog.cat
5 dog.dog.cat
[root@K8S-Node3 ~]# sed -i -r 's/[[:alnum:]]{3}/zxc/' date
[root@K8S-Node3 ~]# cat date
1 zxc.asd.asd
1 zxc.asd.asd
2 zxc.asd.asd
2 zxc.asd.asd
3 zxc.asd.asd
3 zxc.asd.asd
4 zxc.asd.asd
4 zxc.asd.asd
5 zxc.asd.asd
5 zxc.asd.asd
sed -i.bak 's/ac/ab/' files
[root@K8S-Node3 ~]# cat file.bak | grep ac
ac
accc
acs
acs
ac
baaaaaaaaaac
bac
[root@K8S-Node3 ~]# cat file | grep ac
[root@K8S-Node3 ~]# cat file | grep ab
ab
abcc
abs
abs
ab
aaaaabbbc
abbccccc
baaaaaaaaaab
bab
awk
awk语法
awk [options] [BEGIN] {program} [END] [file]
-F 指定分隔符 默认为空格
-f file 指定读取程序的文件名
-v var=value 定义awk程序中使用的变量和默认值
BEGIN:再开始处理数据流之前执行 可选项
program:如何处理数据流 必选项
END:处理数据流之后执行 可选项
awk对字段(列)的提取
$0:表示整行文本
$1:表示第一列
$2:表示第二列
$3:表示第三列
$N:表示第N列
$NF:表示最后一列
[root@K8S-Node3 ~]# awk '{print $1}' test
abc
abc
abc
abc
abc
[root@K8S-Node3 ~]# awk '{print $2}' test
def
def
def
def
def
[root@K8S-Node3 ~]# awk '{print $NF}' test
yz
yz
yz
yz
yz
awk提取记录(行)
使用NR指定行数
[root@K8S-Node3 ~]# free -m
total used free shared buff/cache available
Mem: 3770 869 2150 19 751 2668
Swap: 0 0 0
[root@K8S-Node3 ~]# free -m | awk 'NR==2{print $2}'
3770
#提取第二行的第二列数据
[root@K8S-Node3 ~]# cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
jenkins:x:998:994:Jenkins Automation Server:/var/lib/jenkins:/bin/false
gitlab-www:x:997:993::/var/opt/gitlab/nginx:/bin/false
git:x:996:992::/var/opt/gitlab:/bin/sh
gitlab-redis:x:995:991::/var/opt/gitlab/redis:/bin/false
gitlab-psql:x:994:990::/var/opt/gitlab/postgresql:/bin/sh
registry:x:993:989::/var/opt/gitlab/registry:/bin/sh
gitlab-prometheus:x:992:988::/var/opt/gitlab/prometheus:/bin/sh
user2:x:1000:1000::/home/user2:/bin/bash
user4:x:1001:1001::/home/user4:/bin/bash
user8:x:1002:1002::/home/user8:/bin/bash
user3:x:1003:1003::/home/user3:/bin/bash
user10:x:1004:1004::/home/user10:/bin/bash
user1:x:1005:1005::/home/user1:/bin/bash
user9:x:1006:1006::/home/user9:/bin/bash
user7:x:1007:1007::/home/user7:/bin/bash
user5:x:1008:1008::/home/user5:/bin/bash
user6:x:1009:1009::/home/user6:/bin/bash
[root@K8S-Node3 ~]# awk -F ":" 'NR==2 {print $1}' passwd #指定列分隔符为:答应第二 行第一列的数据
bin
[root@K8S-Node3 ~]# awk -F ":" 'NR==2 {print $1,$3,$5}' passwd
bin 1 bin #打印多列之间用,隔开
[root@K8S-Node3 ~]# awk -F ":" 'NR==2 {print $1 "-" $3 "-" $5}' passwd
bin-1-bin #表示打印多列,列数据间用-隔开
[root@K8S-Node3 ~]# awk -F ":" 'NR==2 {print "account "$1, "UID "$3,"DESC "$5}' passwd
account bin UID 1 DESC bin #给打印出来的列数据加上自定义描述awk '{print "str"$N,"str"$N}'
awk高级用法
awk定义变量
MemTotal: 3861364 kB
MemFree: 2150092 kB
You have new mail in /var/spool/mail/root
[root@K8S-Node3 ~]# head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print t-f*100/t "%"}'
3.86131e+06%
[root@K8S-Node3 ~]# head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print (t-f)*100/t "%"}'
44.3248% #与print之间要用;隔开
awk定义数组(字典)
[root@K8S-Node3 ~]# awk 'BEGIN{dzy[0]=1;dzy[1]=2;print dzy[0],dzy[1]}'
1 2
awk运算
比较运算 > >= < <= == !=
数学运算 + - * 、 % ** ++ --
逻辑运算 && ||
匹配运算 ~ !~ 模糊匹配 == !=属于精确匹配
如果是字符则用ascli编码顺序表比较,如果返回值为1代表真 为0代表假
[root@K8S-Node3 ~]# awk '$1>5{print $0}' test #此语句类似加入了判断,当第一列字段>5 则打印否则 不打印
6
7
8
9
[root@K8S-Node3 ~]# awk '$1>=5{print $0}' test
5
6
7
8
9
[root@K8S-Node3 logs]# du -k * | awk '$1<8{print $0}' | awk '{print $2}'
access.log
数学运算
[root@K8S-Node3 ~]# du -k * | awk 'NR==2{dzy[0]=$1}NR==3{dzy[1]=$1;print dzy[0]+dzy[1]}'
8
[root@K8S-Node3 ~]# du -k * | awk 'NR==3{a=$1}NR==4{b=$1;print a+b}'
1492
[root@K8S-Node3 ~]# du -k * | awk 'NR==3{a=$1}NR==4{b=$1;print a*b}'
5952
[root@K8S-Node3 ~]# du -k * | awk 'NR==3{a=$1}NR==4{b=$1;print a/b}'
0.00268817
[root@K8S-Node3 ~]# du -k * | awk 'NR==3{a=$1}NR==4{b=$1;print a/b*100 "%"}'
0.268817%
[root@K8S-Node3 ~]# du -k * | awk 'NR==3{a=$1}NR==4{b=$1;print a-b}'
-1484
awk环境变量
变量 | 描述 |
---|---|
FIELDWIDTHS | 定义每个数据字段的宽度 |
FS | 指定数据源字段分隔符(列) |
OFS | 输出字段分隔符(列) |
RS | 输入记录分隔符(行) |
ORS | 输出记录分隔符(行) |
[root@K8S-Node3 ~]# awk -F ":" 'BEGIN{FIELDWIDTHS="2 4 5"}NR==1{print $1,$2,$3}' passwd
ro ot:x :0:0:
[root@K8S-Node3 ~]# awk 'BEGIN{FS=":"}NR==1{print $1,$2,$3}' passwd
root x 0 #指定数据源字段分隔符
[root@K8S-Node3 ~]# awk -F ":" 'BEGIN{OFS="@"}NR==1{print $1,$2,$3}' passwd
root@x@0 #指定打印输出分隔符
[root@K8S-Node3 ~]# awk 'BEGIN{FS=":";OFS="@"}NR==1{print $1,$2,$3}' passwd
root@x@0 #FS OFS 结合使用
[root@K8S-Node3 ~]# awk 'BEGIN{RS="\n"}{print $1,$2,$3}' test
1
2
3
4
5
6
7
8
9
You have new mail in /var/spool/mail/root
[root@K8S-Node3 ~]# awk 'BEGIN{RS=""}{print $1,$2,$3}' test
1 2 3
#指定数据源的行分隔符 默认为回车 当设置为""的时候则 行=列 即awk将文件读入内存时 1
2
3
变为
1 2 3
[root@K8S-Node3 ~]# awk 'BEGIN{RS="";OFS="\n"}{print $1,$2,$3}' test
1
2
3
#注意看 此时输出列分隔符为"\n"
[root@K8S-Node3 ~]# awk 'BEGIN{RS="";ORS="@@@"}{print $1,$2,$3}' test
1 2 3@@@[root@K8S-Node3 ~]#
#此时行分隔符为@@@
awk流程控制
[root@K8S-Node3 ~]# awk '{if ($1<5) print $1*2;else print $1/2'} test
2
4
6
8
2.5
3
3.5
4
4.5
或者
[root@K8S-Node3 ~]# awk '{
if ($1<5)
print $1*2
else
print $1/2
}' test
2
4
6
8
2.5
3
3.5
4
4.5
for语句
[root@K8S-Node3 ~]# awk '{
> for (i=1;i<4;i++)
> sum+=$i
> print sum}' num
300
900
1800
[root@K8S-Node3 ~]# awk '{for(i=1;i<4;i++)(sum+=$i);print sum}' num
300
900
1800
while语句
[root@K8S-Node3 ~]# awk '{
sum=0
i=1
while (i<4) {
sum+=$i
i++
}
print sum
}' num
300
600
900
[root@K8S-Node3 ~]# awk '{sum=0;i=1;while (i<4){sum+=$i;i++};print sum}' num
300
600
900
awk小技巧
awk 'END{print NR}' 打印行数
awk 'END{print $0}' 打印最后一行
awk 'END{print NF}' 打印列数
脚本实例
mktemp port_status.XXX 创建临时文件
mktemp -d port_status.XXX 创建临时文件夹