linux常见命令以及shell入门编程(笔记总结记录)

一、linux常见命令

更多命令参考

1.不常用
man diff touch which ssh wc date exit kill id ps sleep uname passwd ping df telnet top sudo su reboot shutdown free rpm useradd yum ip set export
2.常用
cd curl ls/ll cat chmod chown cp find mv rm pwd head tail mkdir scp tar zip unzip gzip xargs let

let:是 BASH 中用于变量计算的工具,用于执行一个或多个表达式

eg:
	[root@localhost learn-shell]# a=1
    [root@localhost learn-shell]# b=2
    [root@localhost learn-shell]# let c=a+b
    [root@localhost learn-shell]# echo $c
    3
    [root@localhost learn-shell]# let c++
    [root@localhost learn-shell]# echo $c
    4
    [root@localhost learn-shell]# let c--
    [root@localhost learn-shell]# echo $c
    3
    [root@localhost learn-shell]# let c+=10
    [root@localhost learn-shell]# echo $c
    13
    [root@localhost learn-shell]# let c-=10
    [root@localhost learn-shell]# echo $c
    3
    [root@localhost learn-shell]# let c=c+10
    [root@localhost learn-shell]# echo $c
    13
    [root@localhost learn-shell]# let c=c-10
    [root@localhost learn-shell]# echo $c
    3
    [root@localhost learn-shell]#
3.数据查找处理相关
grep cut awk sed
1.grep
1.语法
	grep OPTION... [PATTERN] [FILE]...
		
	grep option...[查找的内容]...[file]
	grep option...[查找的内容]...[path]	
		// 注意:使用path,option必须加上-r
		// grep -rn zhuyz ./
		// grep -r '\w' ./
		
备注:查找的内容可以是正则表达式
	
2.作用:对数据进行行提取	

3.option
    -v #对内容进行取反提取(打印出不符合条件的内容)
    -n #对提取的内容显示行号
    -w #精确匹配
    -i #忽略大小写
    ^ #匹配开头行首
    -E #正则匹配
    -r 递归查找文件(当前目录以及子目录下所有所有的文件)
    
4.eg
	grep zhuyz abc*     // 查找当前路径下前缀为abc的所有文件中包含zhuyz字符串的文件,并且打印出该文件的行
	grep zhuyz *.txt    // 查找当前路径下后缀为.txt的所有文件中包含zhuyz字符串的文件,并且打印出该文件的行
	grep -r zhuyz ./	// 递归查找当前目录下以及子目录下的所有文件中包含zhuyz字符串的文件,并且打印出该文件的行
	grep -v zhuyz abc.txt	// 查找abc.txt中不包含有zhuyz字符串的行内容,并且答应出这些行
	grep -rn zhuyz *	// 递归查找当前路径下以及子路径下所有文件 && 显示行号
	grep '\W' abc.txt	// 正则匹配\W:匹配非字母、数字、下划线
生产中查看日志:
	grep -n '2021-02-28 12:00:00' *.log | grep -n 'ERROR' *.log | grep -n 'Exception' *.log
    find ./ -type f -name "*.log" | xargs grep "ERROR|Exception" // 匹配找到当前目录以及子目录下以.log后缀的文件,传递给grep命令执行。
    
2.cut
1.语法
	cut OPTION... [FILE]...
	
2.作用:对数据进行列的提取

3.option
	-d #指定分割符
	-f #指定截取区域
	-c #以字符为单位进行分割

4.eg
-d和-f
	以':'为分隔符,截取出/etc/passwd的第一列跟第三列
	cut -d ':' -f 1,3 /etc/passwd
	
	以':'为分隔符,截取出/etc/passwd的第一列到第三列
	cut -d ':' -f 1-3 /etc/passwd
	
	以':'为分隔符,截取出/etc/passwd的第二列到最后一列
	cut -d ':' -f 2- /etc/passwd
	
-c
	截取/etc/passwd文件从第二个字符到第九个字符
	cut -c 2-9 /etc/passwd
3.awk

参考链接

1.语法
	awk [option] 'script' var=value file(s)
	或awk [option] -f scriptfile var=value file(s)
	
	awk '{[pattern] action}' {filenames}
	awk -F "分隔符" 'script' {filenames}
	awk -v  # 设置变量
	awk -f {awk脚本} {文件名}
	
	awk '条件 {执行动作}'文件名
	awk '条件1 {执行动作} 条件2 {执行动作} ...' 文件名
	或awk [选项] '条件1 {执行动作} 条件2 {执行动作} ...' 文件名
	
	
	
2.作用:对数据进行列的提取

3.eg

    printf #格式化输出,不会自动换行。
    (%ns:字符串型,n代表有多少个字符; %ni:整型,n代表输出几个数字;%.nf:浮点型,n代表的是小数点后有多少个
    小数)
    
    print #打印出内容,默认会自动换行
    \t #制表符
    \n #换行符
    eg:printf '%s\t%s\t%s\t%s\t%s\t%s\n' 1 2 3 4 5 6
    eg:df -h |grep /dev/vda1 | awk '{printf "/dev/vda1的使用率是:"} {print $5}'
    
    小数:echo "scale=2; 0.13 + 0.1" | bc | awk '{printf "%.2f\n", $0}'
    
    $1 #代表第一列
    $2 #代表第二列
    $0 #代表一整行
    eg: df -h | grep /dev/vda1 | awk '{print $5}'
    
    -F #指定分割符
    eg:cat /etc/passwd | awk -F":" '{print $1}'
    
    BEGIN #在读取所有行内容前就开始执行,常常被用于修改内置变量的值
    FS #BEGIN时定义分割符
    eg:cat /etc/passwd | awk 'BEGIN {FS=":"} {print $1}'
    
    END #结束的时候 执行
    NR #行号
    eg:df -h | awk 'NR==2 {print $5}'
    awk '(NR>=20 && NR<=30) {print $1}' /etc/passwd
4.sed

参考

1.语法
	sed [选项][动作] 文件名
	
2.对数据行进行处理(选取,新增,替换,删除,搜索)

3.常见的选项与参数:
    -n #把匹配到的行输出打印到屏幕
    p #以行为单位进行查询,通常与-n一起使用
    eg:df -h | sed -n '2p'

    d #删除
    eg: sed '2d' df.txt	      // 删除第二行
    eg: sed '2,5d' df.txt    // 删除第二行到第五行
    eg: sed '2,$d' df.txt     // 删除第二行到最后一行

    a #在行的下面插入新的内容
    eg: sed '2a 1234567890' df.txt

    i #在行的上面插入新的内容
    eg: sed '2i 1234567890' df.txt
    eg: sed '2,5i 1234567890' df.txt

    c #替换
    eg: sed '2c 1234567890' df.txt
    eg: sed '2,5c 1234567890' df.txt

    s/要被取代的内容/新的字符串/g #指定内容进行替换
    eg: sed 's/0%/100%/g' df.txt

    -i #对源文件进行修改(高危操作,慎用,用之前需要备份源文件)
	eg: sed -i '1i aaa' df.txt        //把aaa写入到df.txt的第一行

    搜索:在文件中搜索内容
    eg:cat -n df.txt | sed -n '/100%/p'

    -e #表示可以执行多条动作
    eg:cat -n df.txt | sed -n -e 's/100%/100%-----100%/g' -e '/100%-----100%/p
    
4.shell命令相关
1.echo
1.作用:字符串的输出

2.可选参数:
	-n     不输出跟随在换行符后的内容
	-e     启用反斜杠转义
	-E     不启用反斜杠转义(默认)
	如果-e有效,则识别字符串中出现的以下:
       \\     反斜杠

       \n     换行

       \r     carriage return

       \t     水平制表符

       \v     垂直制表符
	
3.输出:
	1.普通字符		echo "Hello zhuyz"           // 输出:Hello zhuyz
	2.转义字符		echo "\"Hello zhuyz\""		 // 输出:"Hello zhuyz"
	3.变量		  user_name=zhuyz;echo "${user_name}" 	// 输出:zhuyz
	4.换行		  echo -e "Hello \n zhuyz" # -e 开启转义  // 换行输出
	5.不换行		  echo -e "Hello \c zhuyz"
	6.使用单引号      user_name=zhuyz;echo 'Hello ${user_name}' //原样输出:Hello ${user_name}
2.read
1.作用:从标准输入读取数值

2.可选参数:
    -p:后面跟提示信息,即在输入前打印提示信息。默认不支持"\n"换行
    -s:隐藏输入的内容
    -t:给出等待的时间,超时会退出read
    -n:限制读取字符的个数,触发到临界值会自动执行
    
3.eg:
	echo "请输入姓名:"
	read name
	echo "您输入的姓名是:${name}"
------------------------------------------
	read -p "请输入姓名:" name            // -p 输入前打印提示信息。和其他命令结合,-p一定要放在最后
	echo "您输入的姓名是:${name}"
------------------------------------------
	read -t 5 -p "请输入姓名:" name       // -t 超时等待5s
	echo "您输入的姓名是:${name}"
------------------------------------------
	read -n 3 -p "请输入姓名:" name       // -n 限制输入的字符数
	echo "您输入的姓名是:${name}"
------------------------------------------
##### eg:读取文件内容	
	1.test.txt文件内容为:
        123
        abc
        zhuyz niupi
	
	2.shell脚本内容:
		count=1
		cat test.txt | while read line; do       // 把cat命令的输出作为read的输入,通过while循环read每一行数据
			echo "第${count}行值为:$line"
			$count=$[ $count + 1 ]
		done
		echo "执行完毕"
		
##### eg:读取ls输出的内容:
	1.shell脚本内容如下
        #!/bin/bash
        # read ls
        ls | while read name; do
        echo $name
        done
3.printf
1.作用:格式化输出字符串

2.语法:printf format-string [args...]  // args可为多个,以空格隔开

3.格式化通配符
%s	输出一个字符串	
%d	输出一个整型
%c	输出一个字符	
%f	输出一个浮点数


4.转义字符
常用:\n \r \v \\ 

eg3:
	[root@localhost learn-shell]# printf "%10s %10s %8s\n" zhuyz is dad        // %10s:右对齐占位显示10个字符
		zhuyz         is      dad
	[root@localhost learn-shell]# printf "%-10s %-10s %-8s\n" zhuyz is dad     // %-10s:左对齐占位显示10个字符
	zhuyz      is         dad
	[root@localhost learn-shell]#


eg4:
	[root@localhost learn-shell]# printf "Hello\nzhuyz\n"
	Hello
	zhuyz
	[root@localhost learn-shell]#
	
	


5.常见特殊符号作用
1.	> 覆盖原有内容

2.	>> 追加内容
	
3.	; 命令边界,常用于一次性执行多条命令	
	
4.	| 管道符,用于将两条命令隔开,将前面命令的输出作为后面的输入

5.	&& 前面的命令执行成功,后面的才可以执行

6.	|| 前面的命令执行失败,后面的才可以执行
	
7.	"" 会输出变量值

8.	'' 输出本身内容

9.	`` 命令替换,将反引号内的Linux命令先执行,然后将执行结果赋予变量

10.	2>/dev/null 错误输出到无底洞

11.	1>/dev/null 正确输出到无底洞

1.eg:
	cat >abc.txt
	
2.eg:
	cat >>abc.txt
	
3.eg:
	cat -n abc.txt;ll
	
4.eg:
	cat abc.txt | grep 'zhuyz'
	
5.eg:
	[ -f abc.txt ] && echo "abc.txt文件存在"
	
6.eg:
	[ 1 -gt 2 ] || echo "1不大于2"

7.eg:
	user_name=zhuyz
	echo "${user_name}" // 输出:zhuyz
	
8.eg:
	usser_name=zhuyz
	echo '${user_name}' // 输出:${user_name}

9.eg:
	a=`date`;echo ${a}
	
	
二、shell基础内容
1.变量
1.1.命名规范
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
eg:
a=zhuyz
user_name=zhuyz
userAge=100
1.2.使用变量
1.变量使用以及使用的规范(${})
eg:
    user_name=zhuyz
    echo $user_name
    echo ${user_name} // {}是用来识别变量边界,最好加上
    echo "${user_name}giao"


2.只读变量(readonly)
eg:
    user_name=zhuyz
    readonly user_name // 设置变量为只读,相当于java中的final关键字

3.删除变量(unset)
eg:
    user_name=zhuyz
    unset user_name

4.变量的作用域(局部/全局/环境)

[参考博客](http://c.biancheng.net/view/773.html)

    4.1.局部变量(变量前加local修饰符,不加则代表为全局变量)
    
    eg:(该例子在sh脚本文件中展示)
        funciton func() {
            local user_name=zhuyz
        }
        func
        echo ${user_name} // 输出为空

    4.2.全局变量(作用域:当前shell进程)
    eg:
		user_name=zhuyz
		echo ${user_name}

    4.3.环境变量(作用域:当前shell进程以及子进程)
	eg:
		[root@localhost ~]# user_name=zhuyz       // 定义全局变量user_name
		[root@localhost ~]# echo ${user_name}     // 输出user_name成功
		zhuyz
		[root@localhost ~]# bash                  // 进入shell子进程
		[root@localhost ~]# echo ${user_name}     // 输出user_name失败

		[root@localhost ~]# exit                  // 退出子进程
		exit
		[root@localhost ~]# export user_age=25    // 设置环境变量user_age
		[root@localhost ~]# bash                  // 进入shell子进程         
		[root@localhost ~]# echo ${user_age}      // 输出user_age成功
		25
		[root@localhost ~]# exit
		exit
		[root@localhost ~]#

1.3.shell字符串
1.单引号和双引号区别
见 一、5.常见特殊符号作用 中说明
补充:双引号可以有变量和特殊字符
eg:
	user_name=zhuyz
	user_age=24
	echo "${user_name}\t的年龄是\t${user_age}" // 输出:zhuyz	的年龄是	24
	
	
2.获取字符串长度(${#str})
eg:
	user_name="zhuyz"
	echo ${#user_name} // 输出:5
	
3.截取字符串(${str:start:len})
备注:从start索引位开始截取len个字符(字符串索引下标从0开始)
eg:
	user_name="zhuyz"
	echo ${user_name:0:3} // 输出:zhu

4.字符串拼接(和java不同,变量和常量在一起用双引号,都是变量直接拼接)
eg:
	a=$x$y$z
	b="wo shi ni $d"
	c=$x$y" 牛批"
	key="JAVA_HOME=${JAVA_HOME}"

1.4.shell数组
1.简要描述:一维数组,不支持二维

2.定义:
	arr=(v1 v2 v3 v4 ...)
	或者
	arr[0]=v1
	arr[1]=v2
	arr[n]=vn
	
eg:
	stu_name=(zhuyz1 zhuyz2 zhuyz3)
	或者
	stu_name[0]=zhuyz1
	stu_name[1]=zhuyz2
	stu_name[n]=zhuyzn


3.读取元素
	读取单个元素:${arr[index]}
	读取全部元素:${arr[@]}

4.获取数组长度
	${#arr[@]} 或者 ${#arr[*]}
2.shell注释
1.单行注释:#
eg:
	# by zhuyz
	
	
2.多行注释:和xml标签类似,有标签头和标签尾的感觉
eg1:
    :<<EOF
    注释内容...
    注释内容...
    ...
    EOF

eg2:
	:<<!
    注释内容...
    注释内容...
    ...
	!
备注:eg1中EOF和eg2中的!可以是任意字符,但是需要在开头和结尾都存在
3.shell传递参数
$? #判断上一条命令执行的是否成功
$0 #返回脚本的文件名称
$1-$9 #返回对应的参数值
$* #返回所有的参数值是什么
$# #返回参数的个数和


eg:
	[root@localhost learn-shell]# vi test.sh
	
    #!/bin/bash

    # by zhuyz

    echo "Shell 传递参数实例!";
    echo "执行的文件名:$0";
    echo "第一个参数为:$1";
    echo "第二个参数为:$2";
    echo "第三个参数为:$3";
    echo "传递参数有$#个";
-------------------------------------------------------
    输出:
    [root@localhost learn-shell]# sh test.sh 1 2 3
    Shell 传递参数实例!
    执行的文件名:test.sh
    第一个参数为:1
    第二个参数为:2
    第三个参数为:3
    传递参数有3个
    [root@localhost learn-shell]#
4.运算符
1.算数运算符
+ - \* / % = == !=

==	比较数字是否相等

    eg:(- \* / %和+类似)
        expr $a + $b
        echo $[a+b]
        echo $((a+b))

    eg:
        [ $a==$b ]
	
!=	比较数字是否不等
    eg:
    	[ $a!=$b ]
		
补充:小数的运算(bc计算器)
scale保留多少位小数,scale只对除法,取余数,乘幂 有效,对加减没有效。
    eg:
        echo "scale=2;(0.2+0.3)/1" | bc // 会省略小数点前的0
        echo "scale=2;(1.2+1.3)/1" | bc
		

2.关系运算符(只支持数字)
-eq	-ne	-gt	-lt	-ge -le

eg:
	[ $a -eq $b ]
	
	
3.布尔运算符
!	非
-o	或(有一个表达式为ture,则为true,反之false,前后命令都会执行)
-a	与(两个表达式都为ture,则为true,反之false,前后命令都会执行)

    eg:
        [ !false ] // 表示true
    eg:	
        a=10
        b=20
        [ $a -lt 10 -o $b -gt 20 ]
        [ $a -lt 10 -a $b -gt 20 ]
	

4.逻辑运算符(和java中的&& ||一样,存在短路)
&&	短路与
||	短路或
备注:判断时需要加两个括号[[ expr ]]

    eg:
        a=10
        b=20

        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



5.字符串运算符
=	检测两个字符串是否相等,相等返回 true。
!=	检测两个字符串是否不相等,不相等返回 true。
-z	检测字符串长度是否为0,为0返回 true。
-n	检测字符串长度是否不为 0,不为 0 返回 true。
$	检测字符串是否为空,不为空返回 true。

    eg:
        [ $a=$b ]
        [ $a!=$b ]
        [ -z $a ]
        [ -n $a ]
        [ $a ]
	
	
	
6.文件相关运算符
-d	是否为目录(文件夹)
-f	是否为文件
-e	文件/目录 是否存在,存在文件/目录,则为true
-s	文件大小是否为0,大于0,则为true
-r	文件是否可读
-w	文件是否可写
-x	文件是否可执行

    eg:
        [ -d $directory ]
        [ -f $file ]
        [ -e $file ]
        [ -s $file ]
        [ -r $file ]
        [ -w $file ]
        [ -x $file ]
	
5.流程控制语句
if for case while break continue

1.if
    单分支判断:
    
        if [ 条件判断 ];then
            执行动作
        fi

    单分支判断:    
    
        if [ 条件判断 ];then
            执行动作
        else
            执行动作
        fi

    多分支判断:
    
        if [条件判断];then
            执行动作
        elif [条件判断];then
            执行动作
        elif [条件判断];then
            执行动作
        fi



2.for

template:
	for 变量名 in 值1 值2 值3 ; do
		执行动作
	done
	
eg:
	for i in {1..5} ; do
    	echo $i
	done
-------------------------------------------------	
template:
	for 变量名 in `命令` ; do
		执行动作
	done

eg:
	for i in `seq 1 10` ; do    // seq 1 10 命令是 产生从某个数到另外一个数之间的所有整数的命令(包含起始和结束位置的数字)
		echo $i
	done
-------------------------------------------------
template:
	for (( 条件 )); do
  		执行动作  
	done

eg:
	for (( i = 0; i < 10; i++ )); do
    	echo $i
	done
	
	
	
3.case
和java中的switch case语句类似

template:
	case 值 in
	值1)
    	执行动作1
    ;;
	值2)
        执行动作1
    ;;
	esac

eg:
	read -p "请输入数字: " x
	case $x in
	1)
    	echo "等于1"
	    ;;
	2)
    	echo "等于2"
	    ;;
	esac
	
	
	
4.while

template:
    while [ 条件 ]; do
		执行动作
    done
    
eg:
	i=0
	len=10
	while [ $i -lt $len ]; do
    	echo $i
	    i=$[ $i + 1 ]
	done
-------------------------------------------------
template:
	while(( 条件 )) ; do
    	执行动作
	done
	
eg:
	i=0
	while (( $i<=10 )); do
    	echo "$i"
	    let i++
	done
6.shell函数

shell脚本中也可以定义函数,方法和其他的py、js类似(暂时不记录)

三、shell练习小案例

(案例百度的,实现代码有的简介,有的自己写的)

1.把一个文档前五行中包含字母的行删掉,同时删除6到10行包含的所有字母
0.txt文件内容:
    第1行1234567890不包含字母
    第2行5678asdBBB
    第3行56755AASDDssss
    第4行78asdfDDDDDDD
    第5行123456EEEEEEEE
    第6行1234567ASDF
    第7行56789ASDF
    第8行67890ASDF
    第9行78asdfADSF
    第10行123456AAAA
    第11行67890ASDF
    第12行78asdfADSF
    第13行123456AAAA


实现1:
head -n5 0.txt | sed '/[a-zA-Z]/d' && sed -n '6,10p' 0.txt | sed 's/[a-zA-Z]//g' && sed -n '11,$p' 0.txt


实现2:
sed -n '1,5p' 0.txt | sed '/[a-zA-Z]/d' && sed -n '6,10p' 0.txt | sed 's/[a-zA-Z]//g' && sed -n '11,$p' 0.txt

实现3:编写一个sh脚本
#!/bin/bash

line_number=0
cat 0.txt | while read line ; do
    let line_number++
    if [ $line_number -lt 5 ]; then
        echo $line | sed '/[a-zA-Z]/d'
    elif [ $line_number -gt 6 -a $line_number -lt 10 ]; then
        echo $line | sed 's/[a-zA-Z]//g'
    else
        echo $line
    fi
done
---------------------------------------------------------------------
输出结果都为:
    第1行1234567890不包含字母
    第6行1234567
    第7行56789
    第8行67890
    第9行78
    第10行123456
    第11行67890ASDF
    第12行78asdfADSF
    第13行123456AAAA

2.mysql数据库查询
#!/bin/bash

# mysql数据库查询

read -p '请输入您要查询的学生姓名:' sname
read -p '请输入数据库用户:' user
read -p '请输入数据库名:' database
echo -e "\n"
read -p '请输入数据库密码:' password
sql="select * from admin_user.emp where name='$sname';"
host=192.168.0.108
mysql -h $host  -u $user --password=$password --database=$database  -e "$sql"
exit
3.批量创建linux系统用户
#!/bin/bash

# 批量创建用户
read -p '请输入创建的用户名称:' name
read -p '请输入创建用户的数量:' number

for (( i = 1; i <= $number; i++ )); do
    # 1.查看系统中是否存在用户
    cat /etc/passwd | grep "$name$i" 1>/dev/null
    exists=`echo $?`
    if [ $exists -eq 1 ]; then
        # 2.创建用户
        useradd $name$i 2>/dev/null && echo "创建用户$name$i成功!"
        # 3.给新用户设置密码并把用户名和密码放在文本中
        password=`head -2 /dev/urandom | md5sum | cut -c 1-8`
        echo $password
        #   需要生成随机密码(MD5值),MD5其实是一个算法,用来加密密码
        echo $password | passwd --stdin $name$i 1>/dev/null && echo -e "$name$i\t$password">>/usr/local/newuser_password.txt
    else
        echo "$name$i已经存在,无需再次创建!"
    fi

done
4.内存使用率
#!/bin/bash

# 内存使用率

mem_total=`free -m | sed -n '2p' | awk '{print $2}'`

mem_used=`free -m | sed -n '2p' | awk '{print $3}'`

mem_free=`free -m | sed -n '2p' | awk '{print $4}'`

Percent_mem_used=`echo "scale=2; $mem_used / $mem_total * 100" | bc`

Percent_mem_free=`echo "scale=2; $mem_free / $mem_total * 100" | bc`


now_time=`date +"%Y-%m-%d %H:%M:%S 星期%w"`

echo -e "\n"

echo -e "$now_time\n内存的使用率是:$Percent_mem_used%"

echo -e "内存还剩:$Percent_mem_free%未使用"

# 检查负载是否有压力
# 当已经使用的内容超过1024m
if [ $mem_used -gt 1024 ]; then
    echo -e "\033[31;5m告警:\033[0m"
    echo -e "\033[31;5m内存使用率已超过负载能力,目前使用率达到$Percent_mem_used% \033[0m"
else
    echo "目前内存负载正常"
fi

echo -e "\n"
5.如何获取文本文件的第 10 行
实现1:
	head -10 abc.txt | tail -1

实现2:
	sed -n '10p' abc.txt
6.如何计算本地用户数目
实现1:
	wc -l /etc/passwd | cut -d " " -f 1

实现解释:
    wc -l // 统计行数 && 显示文件名称
    cut -d // 以指定内容为列分隔符
    cut -f // 截取哪一列

实现2:
	wc -l /etc/passwd | awk -F " " '{print $1}'

7.写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令
实现1:
	for i in {0..100..3}; do echo $i; done
实现2:
	for (( i=0; i<=100; i=i+3 )); do echo "Welcome $i times"; done
8.设置zk脚本启动
#!/bin/bash
#
# start/stop/status/restart zk 脚本
#
# chkconfig:   - 80 12
# description:  zookeeper is a centralized service for maintaining configuration information,naming,providing distributed synchronization,and providing group services.

zk_path=/usr/local/apache-zookeeper-3.5.8-bin

key="JAVA_HOME=$JAVA_HOME"

# 查找zkEnv.sh中是否配置了JAVA_HOME=xxx_path的变量
cat $zk_path/bin/zkEnv.sh | sed -n "$key/p"

if [ $? -nq 0 ]; then
    # 写入到zkEnv.sh文件的第一行
    sed -i "1i $key" $zk_path/bin/zkEnv.sh
fi

case $1 in
    start)
        $zk_path/bin/zkServer.sh start $zk_path/conf/zoo.cfg && echo "zk启动成功"
    ;;
    stop)
        $zk_path/bin/zkServer.sh stop && echo "zk停止成功"
    ;;
    status)
        $zk_path/bin/zkServer.sh status
    ;;
    restart)
        $zk_path/bin/zkServer.sh restart && echo "zk重启成功"
    ;;
esac

echo '----zk脚本退出----'

9.查找ip
ifconfig eth1命令输出内容如下:
	eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
	    inet 192.168.11.11  netmask 255.255.255.0  broadcast 192.168.1.255
	    inet6 fe80::a00:27ff:fe8e:2f37  prefixlen 64  scopeid 0x20<link>
	    ether 08:00:27:8e:2f:37  txqueuelen 1000  (Ethernet)
	    RX packets 107782  bytes 10352968 (9.8 MiB)
	    RX errors 0  dropped 0  overruns 0  frame 0
	    TX packets 104521  bytes 9050220 (8.6 MiB)
	    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
	
# 获取到ip地址:192.168.11.11
ifconfig eth1 | sed -n '2p' | awk '{print $2}'						// 检索第2行,再检索输出第2列
ifconfig eth1 | sed -n '2p' | sed 's/^.*et //g' | sed 's/ net.*//g'
ifconfig eth1 | sed -n '2s/^ *[a-z]* *//gp' | awk '{print $1}'		// 正则替换第2行,再检索输出第1列
10.nginx限制访问单位时间内(1s)内请求次数超过5次的ip
    # nginx获取单位时间内相同ip地址访问次数超过5次的ip信息
        
	1.cat access.log
		192.168.11.123 - - [12/Mar/2021:13:36:16 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 3.000
		192.168.11.123 - - [12/Mar/2021:13:36:16 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; 	x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 3.000
		192.168.11.123 - - [12/Mar/2021:13:36:16 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; 		x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 3.000
		192.168.11.123 - - [12/Mar/2021:13:36:16 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 3.000
		192.168.11.123 - - [12/Mar/2021:13:36:16 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 3.000
		192.168.11.123 - - [12/Mar/2021:13:36:16 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 3.000
		192.168.11.123 - - [12/Mar/2021:13:36:43 +0000] "GET /sdfsdfd HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 2.000
		192.168.11.123 - - [12/Mar/2021:13:36:48 +0000] "GET /ahhaha HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 5.000
		192.168.11.123 - - [12/Mar/2021:13:36:53 +0000] "GET /niupi HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 1.000
		192.168.11.123 - - [12/Mar/2021:13:36:58 +0000] "GET /yeah HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-" 10.000  
    
   2.执行脚本limit_ip.sh():
   	#!/bin/bash
 	# limit ip,单位时间内访问超过5次的ip进行检索

	awk '{print $1,$4}' access.log | uniq -c | sort -rn | awk '($1>5) {print $2}' | while read ip; do
		# \$a代表最后一行的下面插入,注意转义一下$,要不然会被当作变量对待
    	sed -i "\$a deny ${ip};" /usr/local/nginx/conf/blacklist.conf
	done
	
	/usr/local/nginx/sbin/nginx -s reload
	echo 'sync limit ip success!!!'
11.对数据中包含逗号的列进行替换操作
背景:mysql数据导出后转换成csv文件,但是由于数据中某个字段的值为[c1,c2,c3]导致csv转换以逗号识别成三个字段的值出现问题。通过shell脚本对该列数据加上双引号操作解决该问题。

1.cat abc.txt
    aaa|bbb|c1,c2,c3|d|e
    fff|nnn|x1,x2,x3|m|p



2.脚本文件
    #!/bin/bash

    filename=$1

    cat $filename | while read line; do
    	# 替换|,并用空格为分隔符分割成数组
        arr=(${line//|/ })
        i=0
        while [ $i -lt ${#arr[@]} ]; do
            if [[ ${arr[$i]} =~ ',' ]]; then
                # 对数据进行加""并替换回去,双引号需要转义
                arr[$i]=\"${arr[$i]}\"
            fi
            let i++
        done
        # 读取数组中所有数据,利用sed把空格替换为|,并且追加写入新文件中
        echo ${arr[@]} | sed 's/ /|/g'>>"new_$filename"
    done

3.执行命令
	[root@localhost learn-shell]# sh test2.sh abc.txt
    [root@localhost learn-shell]# cat new_abc.txt
    aaa|bbb|"c1,c2,c3"|d|e
    fff|nnn|"x1,x2,x3"|m|p
    [root@localhost learn-shell]#

未待完结

Logo

更多推荐