Shell基础语法

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。 [ a =b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ a !=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 创建临时文件夹

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容

  • shell不是面向对象语言 变量 shell中赋值的变量值全部为字符串,不存在数字类型 变量分类全局变量 ≈ 环...
    tom__zhu阅读 60评论 0 1
  • Shell变量 Shell中的变量比较简单,不需要声明。并且只有一种类型:String。可以直接赋值,需要注意的是...
    Jaesoon阅读 290评论 0 0
  • 一、变量赋值,变量传参 定义变量 -- 字母 readonly 变量只读(不可改变值) unset(删除变量...
    绩重KF阅读 1,294评论 0 1
  • 循环 条件判断 数组 变量的引用 函数调用 平时开发过程中,Shell复杂脚本用的并不多, 如果真的很复杂,完全可...
    Alien的小窝阅读 544评论 0 0
  • 搬运 一、主要内容 shell编程 sed命令 awk命令 crontab定时器 二、简介 Shell是用户与内核...
    帅可儿妞阅读 445评论 0 1